11// Based on defmt
22
3- use proc_macro2:: Span ;
43use syn:: {
5- LitStr , Token ,
4+ LitStr , RangeLimits , Token ,
65 parse:: { self , Parse , ParseStream } ,
6+ spanned:: Spanned ,
77} ;
88
99//FOO: i32 = 0, "x * 3.0"
1010//FOO: i32 = 0 // defaults to "x"
11- pub ( crate ) struct Args {
11+ pub ( crate ) struct MetricArgs {
1212 pub ( crate ) name : syn:: Ident ,
1313 pub ( crate ) ty : syn:: Ident ,
1414 pub ( crate ) initial_val : syn:: Expr ,
1515 pub ( crate ) expression_string : syn:: LitStr ,
1616}
1717
18- impl Parse for Args {
18+ impl Parse for MetricArgs {
1919 fn parse ( input : ParseStream ) -> parse:: Result < Self > {
20- let name = input. parse ( ) ?;
20+ let name: syn :: Ident = input. parse ( ) ?;
2121 let _comma: Token ! [ : ] = input. parse ( ) ?;
2222 let ty = input. parse ( ) ?;
2323 let _comma: Token ! [ =] = input. parse ( ) ?;
@@ -29,7 +29,7 @@ impl Parse for Args {
2929 let expression_string = match ( comma, expression_string) {
3030 ( Ok ( _) , Ok ( expr) ) => expr,
3131 ( Ok ( _) , Err ( e) ) => return Err ( e) ,
32- ( Err ( _) , _) => LitStr :: new ( "x" , Span :: mixed_site ( ) ) ,
32+ ( Err ( _) , _) => LitStr :: new ( & name . to_string ( ) , name . span ( ) ) ,
3333 } ;
3434
3535 Ok ( Self {
@@ -40,3 +40,95 @@ impl Parse for Args {
4040 } )
4141 }
4242}
43+
44+ // FOO: i32 = 0, 0..=10, 2
45+ // FOO: i32 = 0, 0..=10, // Step size defaults to 1
46+ // FOO: i32 = 0 // range defaults to the types full range
47+ // TODO Implement the defaults
48+ pub ( crate ) struct SettingArgs {
49+ pub ( crate ) name : syn:: Ident ,
50+ pub ( crate ) ty : syn:: Ident ,
51+ pub ( crate ) initial_val : syn:: Expr ,
52+ pub ( crate ) range_start : syn:: LitFloat ,
53+ pub ( crate ) range_end : syn:: LitFloat ,
54+ pub ( crate ) step_size : syn:: LitFloat ,
55+ }
56+
57+ impl Parse for SettingArgs {
58+ fn parse ( input : ParseStream ) -> parse:: Result < Self > {
59+ let name = input. parse ( ) ?;
60+ let _colon: Token ! [ : ] = input. parse ( ) ?;
61+ let ty = input. parse ( ) ?;
62+ let _eq: Token ! [ =] = input. parse ( ) ?;
63+ let initial_val = input. parse ( ) ?;
64+
65+ let _comma: parse:: Result < Token ! [ , ] > = input. parse ( ) ;
66+ let range: syn:: Expr = input. parse ( ) ?;
67+
68+ let syn:: Expr :: Range ( range) = range else {
69+ panic ! ( "Invalid range" )
70+ } ;
71+
72+ let range_start = range
73+ . start
74+ . expect ( "Only inclusive ranges with both a start and end are supported" ) ;
75+ let range_end = range
76+ . end
77+ . expect ( "Only inclusive ranges with both a start and end are supported" ) ;
78+ assert ! (
79+ matches!( range. limits, RangeLimits :: Closed ( _) ) ,
80+ "Only inclusive ranges with both a start and end are supported"
81+ ) ;
82+
83+ let _comma: parse:: Result < Token ! [ , ] > = input. parse ( ) ;
84+ let step_size: syn:: Lit = input. parse ( ) ?;
85+
86+ let step_size = match step_size {
87+ syn:: Lit :: Int ( i) => syn:: LitFloat :: new ( & format ! ( "{}.0" , i. base10_digits( ) ) , i. span ( ) ) ,
88+ syn:: Lit :: Float ( f) => f,
89+ x => return Err ( syn:: Error :: new ( x. span ( ) , "expected float or int literal" ) ) ,
90+ } ;
91+
92+ Ok ( Self {
93+ name,
94+ ty,
95+ initial_val,
96+ range_start : expr_to_float_lit ( * range_start) ?,
97+ range_end : expr_to_float_lit ( * range_end) ?,
98+ step_size,
99+ } )
100+ }
101+ }
102+
103+ // TODO: Clean up this mess
104+ fn expr_to_float_lit ( e : syn:: Expr ) -> Result < syn:: LitFloat , syn:: Error > {
105+ let error_msg = "expected float or int literal" ;
106+ Ok ( match e {
107+ syn:: Expr :: Lit ( syn:: ExprLit {
108+ lit : syn:: Lit :: Float ( f) ,
109+ ..
110+ } ) => f,
111+ syn:: Expr :: Lit ( syn:: ExprLit {
112+ lit : syn:: Lit :: Int ( i) ,
113+ ..
114+ } ) => syn:: LitFloat :: new ( & format ! ( "{}.0" , i. base10_digits( ) ) , i. span ( ) ) ,
115+ syn:: Expr :: Unary ( syn:: ExprUnary {
116+ op : syn:: UnOp :: Neg ( _) ,
117+ expr,
118+ ..
119+ } ) => match * expr {
120+ syn:: Expr :: Lit ( syn:: ExprLit { lit, .. } ) => match lit {
121+ // TODO: Is there a better way to handle the minus sign?
122+ syn:: Lit :: Int ( i) => {
123+ syn:: LitFloat :: new ( & format ! ( "-{}.0" , i. base10_digits( ) ) , i. span ( ) )
124+ }
125+ syn:: Lit :: Float ( f) => {
126+ syn:: LitFloat :: new ( & format ! ( "-{}" , f. base10_digits( ) ) , f. span ( ) )
127+ }
128+ x => return Err ( syn:: Error :: new ( x. span ( ) , error_msg) ) ,
129+ } ,
130+ x => return Err ( syn:: Error :: new ( x. span ( ) , error_msg) ) ,
131+ } ,
132+ x => return Err ( syn:: Error :: new ( x. span ( ) , error_msg) ) ,
133+ } )
134+ }
0 commit comments