use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use crate::{raw_assert::r#trait, token_store::TokenStore};
use super::{
context::Context,
generatable_set::GeneratableSet,
ident_generator::{self, CountingIdentGenerator},
};
pub struct Store<'a, IdentGenerator = CountingIdentGenerator>
where
IdentGenerator: ident_generator::IdentGenerator,
{
pub(crate) generatables: GeneratableSet<'a>,
pub(crate) ident_gen: IdentGenerator,
}
pub type DefaultStore<'a> = Store<'a, CountingIdentGenerator>;
impl<'a, IdentGenerator> Store<'a, IdentGenerator>
where
IdentGenerator: ident_generator::IdentGenerator,
{
pub fn assert(&mut self, assert: impl r#trait::RawAssertable<'a>) {
assert.do_raw_assert(self);
}
pub fn new() -> Self
where
IdentGenerator: Default,
{
Default::default()
}
}
impl<'a, IdentGenerator> Default for Store<'a, IdentGenerator>
where
IdentGenerator: ident_generator::IdentGenerator + Default,
{
fn default() -> Self {
Self {
generatables: GeneratableSet::new(),
ident_gen: IdentGenerator::default(),
}
}
}
impl<'a, IdentGenerator> ToTokens for Store<'a, IdentGenerator>
where
IdentGenerator: ident_generator::IdentGenerator + Clone,
{
fn to_tokens(&self, tokens: &mut TokenStream) {
let mut ident_gen = self.ident_gen.clone();
let mut context = Context {
ident_generator: &mut ident_gen,
};
let mut token_store = TokenStore::new();
for generatable in self.generatables.iter() {
generatable.generate_into(&mut context, &mut token_store)
}
let asserted_tokens = token_store.into_tokens(&mut context);
tokens.extend(quote! {
#[doc(hidden)]
const _: fn() = || {
#asserted_tokens
};
});
}
}
#[cfg(test)]
mod test {
use quote::ToTokens;
use syn::parse_quote;
use crate::assert_into;
use super::DefaultStore;
#[test]
fn test() {
let generics = syn::Generics::default();
let test_ident: syn::Ident = parse_quote!(Test1);
let mut store = DefaultStore::new();
assert_into!(store | &test_ident with &generics == Test);
assert_into!(store | &test_ident with &generics impl Debug);
println!("{}", store.to_token_stream().to_string());
}
}