macro_tools/equation.rs
1//!
2//! Attributes analyzys and manipulation.
3//!
4
5/// Define a private namespace for all its items.
6mod private
7{
8 #[ allow( clippy::wildcard_imports ) ]
9 use crate::*;
10
11 /// Represents an equation parsed from a procedural macro input.
12 ///
13 /// This struct models an equation consisting of a left-hand side, an operator,
14 /// and a right-hand side. The `Equation` is typically constructed during the
15 /// parsing process of macro input, where the `left` and `op` fields are expected
16 /// to be syntactically represented by `syn::Path` and `syn::BinOp` respectively,
17 /// indicating the variable and operation involved. The `right` field is a
18 /// `proc_macro2::TokenStream`, which can represent more complex expressions
19 /// including, but not limited to, literals, function calls, or further operations.
20 ///
21 /// # Fields
22 /// - `left`: The left-hand side of the equation, represented as a path.
23 /// This could be a variable or a more complex path in the code being
24 /// processed by the macro.
25 ///
26 /// - `op`: The binary operator used in the equation, such as addition,
27 /// subtraction, multiplication, etc.
28 ///
29 /// - `right`: The right-hand side of the equation. Given the potential
30 /// complexity of expressions on this side, it is represented as a
31 /// `proc_macro2::TokenStream` to accommodate any valid Rust expression.
32 ///
33 /// # Examples
34 ///
35 /// Parsing an equation from macro input:
36 ///
37 /// ```rust
38 /// use macro_tools::equation;
39 /// let got : equation::Equation = syn::parse_quote!( default = 31 );
40 /// macro_tools::tree_print!( got );
41 /// assert_eq!( macro_tools::code_to_str!( got ), "default = 31".to_string() );
42 /// ```
43 #[ derive( Debug ) ]
44 pub struct Equation
45 {
46 /// The LHS of the equation, represented by a syntactic path.
47 pub left : syn::Path,
48 // /// The binary operator (e.g., +, -, *, /) of the equation.
49 // pub op : syn::BinOp,
50 /// Equality token.
51 pub op : syn::Token![ = ],
52 /// The RHS of the equation, capable of holding complex expressions.
53 pub right : proc_macro2::TokenStream,
54 }
55
56 impl syn::parse::Parse for Equation
57 {
58 fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self >
59 {
60 let left : syn::Path = input.parse()?;
61 let op : syn::Token![ = ] = input.parse()?;
62 let right : proc_macro2::TokenStream = input.parse()?;
63 Ok( Equation { left, op, right } )
64 }
65 }
66
67 impl quote::ToTokens for Equation
68 {
69 fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
70 {
71 self.left.to_tokens( tokens );
72 self.op.to_tokens( tokens );
73 self.right.to_tokens( tokens );
74 }
75 }
76
77 // impl core::fmt::Display for Equation
78 // {
79 // fn fmt( &self, f : &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result
80 // {
81 // write!( f, "{}", self.left.to_string() );
82 // write!( f, "{}", self.op.to_string() );
83 // write!( f, "{}", self.right.to_string() )
84 // }
85 // }
86
87 ///
88 /// For attribute like `#[former( default = 31 ) ]` return key `default` and value `31`,
89 /// as well as `syn::Meta` as the last element of result tuple.
90 ///
91 /// ### Basic use-case.
92 ///
93 /// ```rust
94 /// use macro_tools::equation;
95 /// let attr : syn::Attribute = syn::parse_quote!( #[ former( default = 31 ) ] );
96 /// // tree_print!( attr );
97 /// let got = equation::from_meta( &attr ).unwrap();
98 /// assert_eq!( macro_tools::code_to_str!( got ), "default = 31".to_string() );
99 /// ```
100 /// # Errors
101 /// qqq: doc
102 pub fn from_meta( attr : &syn::Attribute ) -> Result< Equation >
103 {
104 let meta = &attr.meta;
105 match meta
106 {
107 syn::Meta::List( ref meta_list ) =>
108 {
109 let eq : Equation = syn::parse2( meta_list.tokens.clone() )?;
110 Ok( eq )
111 }
112 _ => Err( syn::Error::new( attr.span(), "Unknown format of attribute, expected syn::Meta::List( meta_list )" ) ),
113 }
114 }
115
116}
117
118#[ doc( inline ) ]
119#[ allow( unused_imports ) ]
120pub use own::*;
121
122/// Own namespace of the module.
123#[ allow( unused_imports ) ]
124pub mod own
125{
126 #[ allow( clippy::wildcard_imports ) ]
127 use super::*;
128 #[ doc( inline ) ]
129 pub use orphan::*;
130 #[ doc( inline ) ]
131 pub use private::
132 {
133 from_meta,
134 };
135}
136
137/// Orphan namespace of the module.
138#[ allow( unused_imports ) ]
139pub mod orphan
140{
141 #[ allow( clippy::wildcard_imports ) ]
142 use super::*;
143 #[ doc( inline ) ]
144 pub use exposed::*;
145}
146
147/// Exposed namespace of the module.
148#[ allow( unused_imports ) ]
149pub mod exposed
150{
151 #[ allow( clippy::wildcard_imports ) ]
152 use super::*;
153 pub use super::super::equation;
154
155 #[ doc( inline ) ]
156 pub use prelude::*;
157 #[ doc( inline ) ]
158 pub use private::
159 {
160 Equation,
161 };
162}
163
164/// Prelude to use essentials: `use my_module::prelude::*`.
165#[ allow( unused_imports ) ]
166pub mod prelude
167{
168 use super::*;
169}