salsa/examples/hello_world/main.rs

83 lines
2.6 KiB
Rust
Raw Normal View History

use salsa::Database;
2018-10-02 09:50:38 +00:00
use std::sync::Arc;
///////////////////////////////////////////////////////////////////////////
2018-10-05 08:54:51 +00:00
// Step 1. Define the database trait
2018-10-02 09:50:38 +00:00
2018-10-05 08:54:51 +00:00
// Define a **database trait** listing out all the prototypes
2018-10-02 09:50:38 +00:00
// that are defined in this section of the code (in real applications
// you would have many of these). For each query, we just give the
// name of the accessor method (`input_string`) and link that to a
// query type (`InputString`) that will be defined later.
salsa::query_group! {
2018-10-05 08:54:51 +00:00
trait HelloWorldDatabase: salsa::Database {
fn input_string(key: ()) -> Arc<String> {
type InputString;
storage input;
}
fn length(key: ()) -> usize {
type Length;
}
2018-10-02 09:50:38 +00:00
}
}
///////////////////////////////////////////////////////////////////////////
// Step 2. Define the queries.
// Define a **function query**. It too has a key and value type, but
// it is defined with a function that -- given the key -- computes the
// value. This function is supplied with a context (an `&impl
2018-10-05 08:54:51 +00:00
// HelloWorldDatabase`) that gives access to other queries. The runtime
2018-10-02 09:50:38 +00:00
// will track which queries you use so that we can incrementally
// update memoized results.
2018-10-05 14:30:17 +00:00
fn length(db: &impl HelloWorldDatabase, (): ()) -> usize {
// Read the input string:
let input_string = db.input_string(());
2018-10-02 09:50:38 +00:00
2018-10-05 14:30:17 +00:00
// Return its length:
input_string.len()
2018-10-02 09:50:38 +00:00
}
///////////////////////////////////////////////////////////////////////////
2018-10-05 08:54:51 +00:00
// Step 3. Define the database struct that implements the database trait
2018-10-02 09:50:38 +00:00
2018-10-05 08:54:51 +00:00
// Define the actual database struct. This must contain a salsa
2018-10-02 09:50:38 +00:00
// runtime but can also contain anything else you need.
#[derive(Default)]
2018-10-05 08:54:51 +00:00
struct DatabaseStruct {
runtime: salsa::runtime::Runtime<DatabaseStruct>,
2018-10-02 09:50:38 +00:00
}
// Tell salsa where to find the runtime in your context.
2018-10-05 08:54:51 +00:00
impl salsa::Database for DatabaseStruct {
fn salsa_runtime(&self) -> &salsa::runtime::Runtime<DatabaseStruct> {
2018-10-02 09:50:38 +00:00
&self.runtime
}
}
// Define the full set of queries that your context needs. This would
2018-10-05 08:54:51 +00:00
// in general combine (and implement) all the database traits in
2018-10-02 09:50:38 +00:00
// your application into one place, allocating storage for all of
// them.
2018-10-05 08:54:51 +00:00
salsa::database_storage! {
struct DatabaseStorage for DatabaseStruct {
impl HelloWorldDatabase {
2018-10-02 09:50:38 +00:00
fn input_string() for InputString;
fn length() for Length;
}
}
}
// This shows how to use a query.
fn main() {
2018-10-05 08:54:51 +00:00
let db = DatabaseStruct::default();
2018-10-02 09:50:38 +00:00
println!("Initially, the length is {}.", db.length(()));
2018-10-02 09:50:38 +00:00
db.query(InputString)
.set((), Arc::new(format!("Hello, world")));
2018-10-02 09:50:38 +00:00
println!("Now, the length is {}.", db.length(()));
2018-10-02 09:50:38 +00:00
}