use quote::quote;
macro_rules! impl_to_tokens_for_newtype {
{$t: ty} => {
impl quote::ToTokens for $t {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.0.to_tokens(tokens)
}
}
};
}
#[derive(Clone)]
pub struct TypeExpr(pub proc_macro2::TokenStream);
impl_to_tokens_for_newtype! {TypeExpr}
impl TypeExpr {
pub fn from_type(ty: &syn::Type) -> Self {
Self(quote! {
#ty
})
}
pub fn bit_len(&self) -> BitLenExpr {
BitLenExpr(quote! {
<#self as ::bitpiece::BitPiece>::BITS
})
}
pub fn fields_ty(&self) -> TypeExpr {
TypeExpr(quote! {
<#self as ::bitpiece::BitPieceHasFields>::Fields
})
}
}
#[derive(Clone)]
pub struct StorageTypeExpr(pub proc_macro2::TokenStream);
impl_to_tokens_for_newtype! {StorageTypeExpr}
impl StorageTypeExpr {
pub fn convert_mut_ref_to_storage_mut_ref(
&self,
mut_ref: proc_macro2::TokenStream,
) -> proc_macro2::TokenStream {
quote! {
<#self as ::bitpiece::BitPiece>::Converter::to_storage_mut_ref(#mut_ref)
}
}
}
#[derive(Clone)]
pub struct BitLenExpr(pub proc_macro2::TokenStream);
impl_to_tokens_for_newtype! {BitLenExpr}
impl BitLenExpr {
pub fn zero() -> Self {
Self(quote! {0})
}
pub fn storage_type(&self) -> TypeExpr {
TypeExpr(quote! {
<::bitpiece::BitLength<{ #self }> as ::bitpiece::AssociatedStorage>::Storage
})
}
}
impl core::ops::Add for BitLenExpr {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(quote! {
(#self) + (#rhs)
})
}
}
impl<'a> core::ops::Add for &'a BitLenExpr {
type Output = BitLenExpr;
fn add(self, rhs: Self) -> Self::Output {
BitLenExpr(quote! {
(#self) + (#rhs)
})
}
}
impl std::iter::Sum for BitLenExpr {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|a, b| a + b).unwrap_or_else(Self::zero)
}
}
pub struct BitOffsetExpr(pub proc_macro2::TokenStream);
impl_to_tokens_for_newtype! {BitOffsetExpr}