diff options
Diffstat (limited to 'macros/src/util')
-rw-r--r-- | macros/src/util/mod.rs | 1 | ||||
-rw-r--r-- | macros/src/util/syn_ext.rs | 114 | ||||
-rw-r--r-- | macros/src/util/syn_path.rs | 26 |
3 files changed, 141 insertions, 0 deletions
diff --git a/macros/src/util/mod.rs b/macros/src/util/mod.rs index 2244229..7ab2185 100644 --- a/macros/src/util/mod.rs +++ b/macros/src/util/mod.rs @@ -2,6 +2,7 @@ pub mod error; pub mod item_impl; pub mod iterator_ext; pub mod string; +pub mod syn_ext; pub mod syn_path; pub mod tokens; diff --git a/macros/src/util/syn_ext.rs b/macros/src/util/syn_ext.rs new file mode 100644 index 0000000..6201670 --- /dev/null +++ b/macros/src/util/syn_ext.rs @@ -0,0 +1,114 @@ +use proc_macro2::Ident; +use syn::punctuated::Punctuated; +use syn::token::Paren; +use syn::{ + Expr, + ExprCall, + ExprLit, + ExprMethodCall, + ExprPath, + GenericMethodArgument, + Lit, + MethodTurbofish, + Path, + Token, +}; + +pub trait ExprMethodCallExt +{ + fn new(receiver: Expr, method: Ident, args: impl IntoIterator<Item = Expr>) -> Self; + + fn with_turbofish(self, turbofish: MethodTurbofish) -> Self; +} + +impl ExprMethodCallExt for ExprMethodCall +{ + fn new(receiver: Expr, method: Ident, args: impl IntoIterator<Item = Expr>) -> Self + { + Self { + attrs: Vec::new(), + receiver: Box::new(receiver), + dot_token: <Token![.]>::default(), + method, + turbofish: None, + paren_token: Paren::default(), + args: Punctuated::from_iter(args), + } + } + + fn with_turbofish(mut self, turbofish: MethodTurbofish) -> Self + { + self.turbofish = Some(turbofish); + + self + } +} + +pub trait ExprPathExt +{ + fn new(path: Path) -> Self; +} + +impl ExprPathExt for ExprPath +{ + fn new(path: Path) -> Self + { + Self { + attrs: Vec::new(), + qself: None, + path, + } + } +} + +pub trait MethodTurbofishExt +{ + fn new(args: impl IntoIterator<Item = GenericMethodArgument>) -> Self; +} + +impl MethodTurbofishExt for MethodTurbofish +{ + fn new(args: impl IntoIterator<Item = GenericMethodArgument>) -> Self + { + Self { + colon2_token: <Token![::]>::default(), + lt_token: <Token![<]>::default(), + args: Punctuated::from_iter(args), + gt_token: <Token![>]>::default(), + } + } +} + +pub trait ExprCallExt +{ + fn new(function: Expr, args: impl IntoIterator<Item = Expr>) -> Self; +} + +impl ExprCallExt for ExprCall +{ + fn new(function: Expr, args: impl IntoIterator<Item = Expr>) -> Self + { + Self { + attrs: Vec::new(), + func: Box::new(function), + paren_token: Paren::default(), + args: Punctuated::from_iter(args), + } + } +} + +pub trait ExprLitExt +{ + fn new(lit: impl Into<Lit>) -> Self; +} + +impl ExprLitExt for ExprLit +{ + fn new(lit: impl Into<Lit>) -> Self + { + Self { + attrs: Vec::new(), + lit: lit.into(), + } + } +} diff --git a/macros/src/util/syn_path.rs b/macros/src/util/syn_path.rs index 88182cc..26e2597 100644 --- a/macros/src/util/syn_path.rs +++ b/macros/src/util/syn_path.rs @@ -32,3 +32,29 @@ impl SynPathExt for syn::Path ) } } + +macro_rules! syn_path { + ($first_segment: ident $(::$segment: ident)*) => { + ::syn::Path { + leading_colon: None, + segments: ::syn::punctuated::Punctuated::from_iter([ + $crate::util::syn_path::syn_path_segment!($first_segment), + $($crate::util::syn_path::syn_path_segment!($segment),)* + ]) + } + }; +} + +macro_rules! syn_path_segment { + ($segment: ident) => { + ::syn::PathSegment { + ident: ::proc_macro2::Ident::new( + stringify!($segment), + ::proc_macro2::Span::call_site(), + ), + arguments: ::syn::PathArguments::None, + } + }; +} + +pub(crate) use {syn_path, syn_path_segment}; |