aboutsummaryrefslogtreecommitdiff
path: root/macros/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/util')
-rw-r--r--macros/src/util/mod.rs1
-rw-r--r--macros/src/util/syn_ext.rs114
-rw-r--r--macros/src/util/syn_path.rs26
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};