use proc_macro2::Span;
use syn::punctuated::Punctuated;
use syn::Expr;
use syn::Path;
use syn::PathSegment;
pub(crate) type MacroResult = std::result::Result<proc_macro::TokenStream, proc_macro::TokenStream>;
pub(crate) fn synerr_to_tokens(err: syn::Error) -> proc_macro::TokenStream {
err.to_compile_error().into()
}
pub(crate) fn adapt_ident_with_self(expr: &mut Expr) -> bool {
let adaption: Option<syn::ExprField> = match &expr {
Expr::Path(orig_path) => {
if orig_path.path.segments.len() == 1 {
let ident = orig_path.path.segments.first().unwrap().ident.clone();
let self_segment = PathSegment {
ident: syn::Ident::new("self", Span::call_site()),
arguments: syn::PathArguments::None,
};
let mut segments = Punctuated::new();
segments.push(self_segment);
Some(syn::ExprField {
attrs: vec![],
base: Box::new(Expr::Path(syn::ExprPath {
attrs: vec![],
qself: None,
path: Path {
leading_colon: None,
segments,
},
})),
dot_token: Default::default(),
member: syn::Member::Named(ident),
})
} else {
None
}
}
_ => None,
};
if let Some(a) = adaption {
*expr = Expr::Field(a);
true
} else {
false
}
}