定义数据库结构体
首先,我们需要创建数据库结构体。 通常它只会被应用程序的“驱动代码”使用, 也就是负责启动程序、提供输入并转发输出的那一部分。
在 calc 中,数据库结构体位于 db 模块里,形式如下:
#![allow(unused)] fn main() { #[salsa::db] #[derive(Clone)] #[cfg_attr(not(test), derive(Default))] pub struct CalcDatabaseImpl { storage: salsa::Storage<Self>, // The logs are only used for testing and demonstrating reuse: #[cfg(test)] logs: Arc<Mutex<Option<Vec<String>>>>, } #[cfg(test)] impl Default for CalcDatabaseImpl { fn default() -> Self { let logs = <Arc<Mutex<Option<Vec<String>>>>>::default(); Self { storage: salsa::Storage::new(Some(Box::new({ let logs = logs.clone(); move |event| { eprintln!("Event: {event:?}"); // Log interesting events, if logging is enabled if let Some(logs) = &mut *logs.lock().unwrap() { // only log interesting events if let salsa::EventKind::WillExecute { .. } = event.kind { logs.push(format!("Event: {event:?}")); } } } }))), logs, } } } }
#[salsa::db] 属性会把这个结构体标记为数据库。
它必须包含一个名为 storage 的字段,其类型为 salsa::Storage<Self>,
但你也可以根据需要添加其他字段。
实现 salsa::Database trait
除了结构体本身,我们还必须实现 salsa::Database:
#![allow(unused)] fn main() { #[salsa::db] impl salsa::Database for CalcDatabaseImpl {} }