mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-24 22:03:34 +00:00
make the QueryTable
impl totally generic
This commit is contained in:
parent
2924e98f40
commit
8ad5051a74
3 changed files with 33 additions and 60 deletions
|
@ -49,12 +49,6 @@ pub(crate) fn database_storage(input: TokenStream) -> TokenStream {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let each_query = || {
|
||||
query_groups
|
||||
.iter()
|
||||
.flat_map(|query_group| query_group.queries.iter().map(move |q| (query_group, q)))
|
||||
};
|
||||
|
||||
// For each query group `foo::MyGroup` create a link to its
|
||||
// `foo::MyGroupGroupStorage`
|
||||
let mut storage_fields = proc_macro2::TokenStream::new();
|
||||
|
@ -187,52 +181,6 @@ pub(crate) fn database_storage(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
});
|
||||
|
||||
let mut for_each_query_table = proc_macro2::TokenStream::new();
|
||||
for (
|
||||
query_group,
|
||||
Query {
|
||||
query_name,
|
||||
query_type,
|
||||
},
|
||||
) in each_query()
|
||||
{
|
||||
let group_storage = query_group.group_storage();
|
||||
let group_descriptor = query_group.group_descriptor();
|
||||
|
||||
for_each_query_table.extend(quote! {
|
||||
impl ::salsa::plumbing::GetQueryTable<#query_type> for #database_name {
|
||||
fn get_query_table(
|
||||
db: &Self,
|
||||
) -> ::salsa::QueryTable<'_, Self, #query_type> {
|
||||
let storage: &#group_storage<#database_name> = ::salsa::plumbing::GetQueryGroupStorage::from(db);
|
||||
::salsa::QueryTable::new(
|
||||
db,
|
||||
&storage.#query_name,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_query_table_mut(
|
||||
db: &mut Self,
|
||||
) -> ::salsa::QueryTableMut<'_, Self, #query_type> {
|
||||
let db = &*db;
|
||||
let storage: &#group_storage<#database_name> = ::salsa::plumbing::GetQueryGroupStorage::from(db);
|
||||
::salsa::QueryTableMut::new(
|
||||
db,
|
||||
&storage.#query_name,
|
||||
)
|
||||
}
|
||||
|
||||
fn descriptor(
|
||||
db: &Self,
|
||||
key: <#query_type as ::salsa::Query<Self>>::Key,
|
||||
) -> <Self as ::salsa::plumbing::DatabaseStorageTypes>::QueryDescriptor {
|
||||
<Self as ::salsa::plumbing::GetDatabaseDescriptor<_>>::from(#group_descriptor::#query_name(key))
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
output.extend(for_each_query_table);
|
||||
output.extend(storage_impls);
|
||||
output.extend(descriptor_impls);
|
||||
|
||||
|
@ -254,7 +202,6 @@ struct DatabaseStorage {
|
|||
|
||||
struct QueryGroup {
|
||||
query_group: Path,
|
||||
queries: Vec<Query>,
|
||||
}
|
||||
|
||||
impl QueryGroup {
|
||||
|
@ -299,6 +246,7 @@ impl QueryGroup {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Query {
|
||||
query_name: Ident,
|
||||
query_type: Path,
|
||||
|
@ -336,11 +284,8 @@ impl Parse for QueryGroup {
|
|||
let query_group: Path = input.parse()?;
|
||||
let content;
|
||||
syn::braced!(content in input);
|
||||
let queries: Vec<Query> = parse_while(Token![fn ], &content)?;
|
||||
Ok(QueryGroup {
|
||||
query_group,
|
||||
queries,
|
||||
})
|
||||
let _queries: Vec<Query> = parse_while(Token![fn ], &content)?;
|
||||
Ok(QueryGroup { query_group })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -199,12 +199,11 @@ pub(crate) fn query_group(args: TokenStream, input: TokenStream) -> TokenStream
|
|||
|
||||
// Emit an impl of the trait
|
||||
output.extend({
|
||||
let qts = queries.iter().map(|q| &q.query_type);
|
||||
let bounds = &input.supertraits;
|
||||
quote! {
|
||||
impl<T> #trait_name for T
|
||||
where
|
||||
T: #(salsa::plumbing::GetQueryTable<#qts> +)* #bounds,
|
||||
T: #bounds,
|
||||
T: ::salsa::plumbing::GetQueryGroupStorage<#group_storage<T>>,
|
||||
T: ::salsa::plumbing::GetDatabaseDescriptor<#group_descriptor>,
|
||||
{
|
||||
|
|
|
@ -81,6 +81,35 @@ pub trait GetQueryTable<Q: Query<Self>>: Database {
|
|||
fn descriptor(db: &Self, key: Q::Key) -> Self::QueryDescriptor;
|
||||
}
|
||||
|
||||
impl<DB, Q> GetQueryTable<Q> for DB
|
||||
where
|
||||
DB: Database,
|
||||
Q: Query<DB>,
|
||||
DB: GetQueryGroupStorage<Q::GroupStorage>,
|
||||
DB: GetDatabaseDescriptor<Q::GroupDescriptor>,
|
||||
{
|
||||
fn get_query_table(db: &DB) -> QueryTable<'_, DB, Q> {
|
||||
let group_storage: &Q::GroupStorage = GetQueryGroupStorage::from(db);
|
||||
let query_storage = Q::storage(group_storage);
|
||||
QueryTable::new(db, query_storage)
|
||||
}
|
||||
|
||||
fn get_query_table_mut(db: &mut DB) -> QueryTableMut<'_, DB, Q> {
|
||||
let db = &*db;
|
||||
let group_storage: &Q::GroupStorage = GetQueryGroupStorage::from(db);
|
||||
let query_storage = Q::storage(group_storage);
|
||||
QueryTableMut::new(db, query_storage)
|
||||
}
|
||||
|
||||
fn descriptor(
|
||||
_db: &DB,
|
||||
key: <Q as Query<DB>>::Key,
|
||||
) -> <DB as DatabaseStorageTypes>::QueryDescriptor {
|
||||
let group_descriptor = Q::descriptor(key);
|
||||
<DB as GetDatabaseDescriptor<_>>::from(group_descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the "group storage" with type `S` from the database.
|
||||
///
|
||||
/// This basically moves from the full context of the database to the context
|
||||
|
|
Loading…
Reference in a new issue