mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-02 09:46:06 +00:00
first shot at parsing database-storage in syn
This commit is contained in:
parent
d15be76350
commit
7b6254924e
2 changed files with 120 additions and 0 deletions
114
components/salsa-macros/src/database_storage.rs
Normal file
114
components/salsa-macros/src/database_storage.rs
Normal file
|
@ -0,0 +1,114 @@
|
|||
use crate::parenthesized::Parenthesized;
|
||||
use proc_macro::TokenStream;
|
||||
use syn::parse::{Parse, ParseStream, Peek};
|
||||
use syn::{Ident, Path, Token};
|
||||
|
||||
/// Implementation for `salsa::database_storage!` macro.
|
||||
///
|
||||
/// Current syntax:
|
||||
///
|
||||
/// ```
|
||||
/// salsa::database_storage! {
|
||||
/// struct DatabaseStorage for DatabaseStruct {
|
||||
/// impl HelloWorldDatabase {
|
||||
/// fn input_string() for InputString;
|
||||
/// fn length() for LengthQuery;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// impl Database {
|
||||
pub(crate) fn database_storage(input: TokenStream) -> TokenStream {
|
||||
let _input: DatabaseStorage = syn::parse_macro_input!(input as DatabaseStorage);
|
||||
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
struct DatabaseStorage {
|
||||
storage_struct_name: Ident,
|
||||
database_name: Path,
|
||||
query_groups: Vec<QueryGroup>,
|
||||
}
|
||||
|
||||
struct QueryGroup {
|
||||
query_group: Path,
|
||||
queries: Vec<Query>,
|
||||
}
|
||||
|
||||
struct Query {
|
||||
query_name: Ident,
|
||||
query_type: Path,
|
||||
}
|
||||
|
||||
impl Parse for DatabaseStorage {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let _struct_token: Token![struct ] = input.parse()?;
|
||||
let storage_struct_name: Ident = input.parse()?;
|
||||
let _for_token: Token![for ] = input.parse()?;
|
||||
let database_name: Path = input.parse()?;
|
||||
let content;
|
||||
syn::braced!(content in input);
|
||||
let query_groups: Vec<QueryGroup> = parse_while(Token![impl ], &content)?;
|
||||
Ok(DatabaseStorage {
|
||||
storage_struct_name,
|
||||
database_name,
|
||||
query_groups,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for QueryGroup {
|
||||
/// ```ignore
|
||||
/// impl HelloWorldDatabase {
|
||||
/// fn input_string() for InputString;
|
||||
/// fn length() for LengthQuery;
|
||||
/// }
|
||||
/// ```
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let _fn_token: Token![impl ] = input.parse()?;
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Query {
|
||||
/// ```ignore
|
||||
/// fn input_string() for InputString;
|
||||
/// ```
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let _fn_token: Token![fn ] = input.parse()?;
|
||||
let query_name: Ident = input.parse()?;
|
||||
let _unit: Parenthesized<Nothing> = input.parse()?;
|
||||
let _for_token: Token![for ] = input.parse()?;
|
||||
let query_type: Path = input.parse()?;
|
||||
let _for_token: Token![;] = input.parse()?;
|
||||
Ok(Query {
|
||||
query_name,
|
||||
query_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Nothing;
|
||||
|
||||
impl Parse for Nothing {
|
||||
fn parse(_input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(Nothing)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_while<P: Peek + Copy, B: Parse>(peek: P, input: ParseStream) -> syn::Result<Vec<B>> {
|
||||
let mut result = vec![];
|
||||
while input.peek(peek) {
|
||||
let body: B = input.parse()?;
|
||||
result.push(body);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
|
@ -9,6 +9,7 @@ extern crate quote;
|
|||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
mod database_storage;
|
||||
mod parenthesized;
|
||||
mod query_group;
|
||||
|
||||
|
@ -124,3 +125,8 @@ mod query_group;
|
|||
pub fn query_group(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
query_group::query_group(args, input)
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn database_storage(input: TokenStream) -> TokenStream {
|
||||
database_storage::database_storage(input)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue