use proc_macro2::TokenStream;
use quote::{quote_spanned, ToTokens};
use syn::{parse::Parse, spanned::Spanned, Result};
use crate::{derive_flag::DeriveFlag, newtype::Newtype};
pub trait WrapperFunction: Parse + ToTokens {}
pub trait WrapperImplementor: 'static {
type Function: WrapperFunction;
fn module_name() -> &'static str;
fn generate_newtype_definition(&mut self, new_type: &Newtype) -> Result<TokenStream>;
fn generate_newtype_implementation<'a, I: Iterator<Item = &'a Self::Function>>(
&mut self,
new_type: &'a Newtype,
functions: I,
) -> Result<TokenStream>;
fn generate_derive_flag_functions<'a, I: Iterator<Item = &'a DeriveFlag>>(
&mut self,
new_type: &'a Newtype,
derive_flags: I,
) -> Result<Vec<Self::Function>>;
fn generate_newtype_functions(&mut self, new_type: &Newtype) -> Result<Vec<Self::Function>>;
fn generate(&mut self, new_type: Newtype) -> Result<TokenStream> {
let definition = self.generate_newtype_definition(&new_type)?;
let mut functions =
self.generate_derive_flag_functions(&new_type, new_type.args.flags.iter())?;
functions.extend(self.generate_newtype_functions(&new_type)?);
let implementation = self.generate_newtype_implementation(&new_type, functions.iter())?;
Ok(quote_spanned! {new_type.span()=>
#definition
#implementation
})
}
}