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}