syn_args/
lib.rs

1#![doc = include_str!("../readme.md")]
2mod macro_args;
3mod syn_args;
4mod traits;
5mod transform;
6
7pub use macro_args::*;
8pub use syn_args::*;
9pub use syn_args_derive as derive;
10pub use traits::*;
11pub use transform::*;
12
13#[cfg(test)]
14mod tests {
15
16    use syn::Error;
17    use traits::ArgsParse;
18    use utils::ewc;
19
20    use super::*;
21
22    #[derive(Debug, PartialEq)]
23    pub enum ModuleArgs {
24        F1(def::Int, def::Int),
25        F2(def::Int),
26        F3(def::Expr),
27        F4(def::Array<def::Expr>),
28        F5(ModuleSubObj),
29        F6(def::Array<ModuleSubObj>),
30        F7(SubWrap),
31        F9(def::String, def::Extends<def::Bool>),
32        F8(def::Option<T1>),
33    }
34
35    impl TryFrom<&Value> for ModuleArgs {
36        type Error = Error;
37        fn try_from(v: &Value) -> Result<Self, Error> {
38            let mut err = Error::new(proc_macro2::Span::call_site(), "Expected ModuleArgs");
39            if let Value::Array(args) = v {
40                match ewc::<_, _, syn::Error>(|| Ok(ModuleArgs::F1(Transform::new(v, "0").try_into()?, Transform::new(v, "1").try_into()?))) {
41                    Ok(rt) => return Ok(rt),
42                    Err(e) => err = e,
43                }
44
45                match Transform::new(v, "0").try_into() {
46                    Ok(rt) => return Ok(ModuleArgs::F2(rt)),
47                    Err(e) => err = e,
48                }
49
50                match Transform::new(v, "0").try_into() {
51                    Ok(rt) => return Ok(ModuleArgs::F3(rt)),
52                    Err(e) => err = e,
53                }
54
55                match Transform::new(v, "0").try_into() {
56                    Ok(rt) => return Ok(ModuleArgs::F4(rt)),
57                    Err(e) => err = e,
58                }
59
60                match Transform::new(v, "0").try_into() {
61                    Ok(rt) => return Ok(ModuleArgs::F5(rt)),
62                    Err(e) => err = e,
63                }
64
65                match Transform::new(v, "0").try_into() {
66                    Ok(rt) => return Ok(ModuleArgs::F6(rt)),
67                    Err(e) => err = e,
68                }
69
70                match Transform::new(v, "0").try_into() {
71                    Ok(rt) => return Ok(ModuleArgs::F7(rt)),
72                    Err(e) => err = e,
73                }
74
75                match ewc::<_, _, syn::Error>(|| Ok(ModuleArgs::F9(Transform::new(v, "0").try_into()?, Transform::new(v, "1").try_into()?))) {
76                    Ok(rt) => return Ok(rt),
77                    Err(e) => err = e,
78                }
79
80                match Transform::new(v, "0").try_into() {
81                    Ok(rt) => return Ok(ModuleArgs::F8(rt)),
82                    Err(e) => err = e,
83                }
84            }
85
86            Err(err)
87        }
88    }
89
90    impl TryFrom<Value> for ModuleArgs {
91        type Error = Error;
92        fn try_from(v: Value) -> Result<Self, Error> {
93            ModuleArgs::try_from(&v)
94        }
95    }
96
97    impl ArgsParse for ModuleArgs {
98        fn parse(input: &str) -> Result<Self, Error> {
99            Formal::new().parse(input)?.try_into()
100        }
101    }
102
103    impl TryFrom<Arguments> for ModuleArgs {
104        type Error = Error;
105
106        fn try_from(value: Arguments) -> Result<Self, Self::Error> {
107            Self::try_from(&value.0)
108        }
109    }
110
111    impl TryFrom<Transform<'_>> for ModuleArgs {
112        type Error = Error;
113
114        fn try_from(value: Transform) -> Result<Self, Self::Error> {
115            if let Value::Object(obj) = value.value {
116                if let Some(v) = obj.get(value.key) {
117                    return v.try_into();
118                }
119            }
120
121            Err(Error::new(proc_macro2::Span::call_site(), "Expected ModuleArgs"))
122        }
123    }
124
125    #[derive(Debug, PartialEq)]
126    pub struct ModuleSubObj {
127        pub global: def::Option<def::Bool>,
128        pub imports: def::Array<def::Expr>,
129        pub sub: def::Option<Sub>,
130    }
131
132    impl TryFrom<&Value> for ModuleSubObj {
133        type Error = Error;
134
135        fn try_from(value: &Value) -> Result<Self, Self::Error> {
136            println!("ModuleSubObj: {:?}", value);
137            if let Value::Object(_) = value {
138                return Ok(ModuleSubObj {
139                    imports: Transform::new(value, "imports").try_into()?,
140                    global: Transform::new(value, "global").try_into()?,
141                    sub: Transform::new(value, "sub").try_into()?,
142                });
143            }
144
145            Err(Error::new(proc_macro2::Span::call_site(), "Expected ModuleSubObj"))
146        }
147    }
148
149    impl TryFrom<Arguments> for ModuleSubObj {
150        type Error = Error;
151
152        fn try_from(value: Arguments) -> Result<Self, Self::Error> {
153            if let Value::Array(v) = value.0 {
154                if let Some(value) = v.first() {
155                    return Self::try_from(value);
156                }
157            }
158            Err(Error::new(proc_macro2::Span::call_site(), "Arguments ModuleSubObj"))
159        }
160    }
161
162    impl TryFrom<Transform<'_>> for ModuleSubObj {
163        type Error = Error;
164
165        fn try_from(value: Transform) -> Result<Self, Self::Error> {
166            if let Value::Object(obj) = value.value {
167                if let Some(v) = obj.get(value.key) {
168                    return v.try_into();
169                }
170            } else if let Value::Array(v) = value.value {
171                let index = value.key.parse::<usize>().unwrap();
172                if let Some(value) = v.get(index) {
173                    return Self::try_from(value);
174                }
175            }
176
177            Err(Error::new(proc_macro2::Span::call_site(), "Expected ModuleSubObj"))
178        }
179    }
180
181    #[derive(Debug, PartialEq)]
182    pub struct Sub {
183        pub value: def::Bool,
184    }
185
186    impl TryFrom<&Value> for Sub {
187        type Error = Error;
188
189        fn try_from(value: &Value) -> Result<Self, Self::Error> {
190            if let Value::Object(_) = value {
191                return Ok(Sub { value: Transform::new(value, "value").try_into()? });
192            }
193
194            Err(Error::new(proc_macro2::Span::call_site(), "Expected Sub"))
195        }
196    }
197
198    impl TryFrom<Value> for Sub {
199        type Error = Error;
200
201        fn try_from(value: Value) -> Result<Self, Self::Error> {
202            Sub::try_from(&value)
203        }
204    }
205
206    impl TryFrom<Transform<'_>> for Sub {
207        type Error = Error;
208
209        fn try_from(value: Transform) -> Result<Self, Self::Error> {
210            if let Value::Object(obj) = value.value {
211                if let Some(v) = obj.get(value.key) {
212                    return v.try_into();
213                }
214            }
215
216            Err(Error::new(proc_macro2::Span::call_site(), "Expected SubWrap"))
217        }
218    }
219
220    #[derive(Debug, PartialEq)]
221    pub struct SubWrap {
222        pub s1: Sub,
223        pub s2: Sub,
224    }
225
226    impl TryFrom<&Value> for SubWrap {
227        type Error = Error;
228
229        fn try_from(value: &Value) -> Result<Self, Self::Error> {
230            if let Value::Object(_) = value {
231                return Ok(SubWrap { s1: Transform::new(value, "s1").try_into()?, s2: Transform::new(value, "s2").try_into()? });
232            }
233
234            Err(Error::new(proc_macro2::Span::call_site(), "Expected SubWrap"))
235        }
236    }
237
238    impl TryFrom<Value> for SubWrap {
239        type Error = Error;
240
241        fn try_from(value: Value) -> Result<Self, Self::Error> {
242            SubWrap::try_from(&value)
243        }
244    }
245
246    impl TryFrom<Transform<'_>> for SubWrap {
247        type Error = Error;
248
249        fn try_from(value: Transform) -> Result<Self, Self::Error> {
250            if let Value::Object(obj) = value.value {
251                if let Some(v) = obj.get(value.key) {
252                    return v.try_into();
253                }
254            } else if let Value::Array(v) = value.value {
255                let index = value.key.parse::<usize>().unwrap();
256                if let Some(value) = v.get(index) {
257                    return Self::try_from(value);
258                }
259            }
260
261            Err(Error::new(proc_macro2::Span::call_site(), "Expected SubWrap"))
262        }
263    }
264
265    #[derive(Debug, PartialEq)]
266    struct T1 {
267        pub controllers: def::Option<def::Array<def::Expr>>,
268    }
269
270    impl TryFrom<&Value> for T1 {
271        type Error = Error;
272
273        fn try_from(value: &Value) -> Result<Self, Self::Error> {
274            if let Value::Object(_) = value {
275                return Ok(T1 { controllers: Transform::new(value, "controllers").try_into()? });
276            }
277
278            Err(Error::new(proc_macro2::Span::call_site(), "Expected T1"))
279        }
280    }
281
282    impl TryFrom<Transform<'_>> for T1 {
283        type Error = Error;
284
285        fn try_from(value: Transform<'_>) -> Result<Self, Self::Error> {
286            println!("{:?} {:?}", value.key, value.value);
287            if let Value::Object(obj) = value.value {
288                if let Some(v) = obj.get(value.key) {
289                    return v.try_into();
290                }
291            } else if let Value::Array(v) = value.value {
292                let index = value.key.parse::<usize>().unwrap();
293                if let Some(value) = v.get(index) {
294                    return Self::try_from(value);
295                }
296            }
297
298            Err(Error::new(proc_macro2::Span::call_site(), "Expected T1"))
299        }
300    }
301
302    #[test]
303    fn test_formal_f1() {
304        let f = Formal::new();
305
306        // fm.parse("F(Object{ a: Int, b: Optional(Int) }, Array(Int))");
307        let args = f.parse("F(1, 3)").unwrap();
308        // let args = f.parse("F(1)").unwrap();
309        // let args = f.parse("F(Hello)").unwrap();
310        println!("{:?}", args);
311
312        let res = ModuleArgs::try_from(args).unwrap();
313        println!("{:?}", res);
314
315        assert_eq!(res, ModuleArgs::F1(def::Int(1), def::Int(3)));
316    }
317
318    #[test]
319    fn test_formal_f2() {
320        let f = Formal::new();
321
322        let args = f.parse("F(1)").unwrap();
323        // let args = f.parse("F(Hello)").unwrap();
324        println!("{:?}", args);
325
326        let res = ModuleArgs::try_from(args).unwrap();
327        println!("{:?}", res);
328
329        assert_eq!(res, ModuleArgs::F2(def::Int(1)));
330    }
331
332    #[test]
333    fn test_formal_f3() {
334        let res = ModuleArgs::parse("F(Hello)").unwrap();
335        println!("{:?}", res);
336
337        assert_eq!(res, ModuleArgs::F3(def::Expr::from("Hello")));
338    }
339
340    #[test]
341    fn test_formal_f4() {
342        let res = ModuleArgs::parse("F([Ident1, Ident2])").unwrap();
343        println!("{:?}", res);
344
345        assert_eq!(res, ModuleArgs::F4(def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")])));
346    }
347
348    #[test]
349    fn test_formal_f5() {
350        let res = ModuleArgs::parse("F({ imports: [Ident1, Ident2] })").unwrap();
351        println!("{:?}", res);
352
353        assert_eq!(
354            res,
355            ModuleArgs::F5(ModuleSubObj {
356                imports: def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")]),
357                global: def::Option(None),
358                sub: def::Option(None)
359            })
360        );
361    }
362
363    #[test]
364    fn test_formal_f6() {
365        let res = ModuleArgs::parse("F([{ imports: [Ident1, Ident2] }, { imports: [Ident3, Ident4] }])").unwrap();
366        println!("{:?}", res);
367
368        assert_eq!(
369            res,
370            ModuleArgs::F6(def::Array(vec![
371                ModuleSubObj {
372                    imports: def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")]),
373                    global: def::Option(None),
374                    sub: def::Option(None)
375                },
376                ModuleSubObj {
377                    imports: def::Array(vec![def::Expr::from("Ident3"), def::Expr::from("Ident4")]),
378                    global: def::Option(None),
379                    sub: def::Option(None)
380                }
381            ]))
382        );
383    }
384
385    #[test]
386    fn test_formal_f6_2() {
387        let res = ModuleArgs::parse("F([{ imports: [Ident1, Ident2], global: true }, { imports: [Ident3, Ident4] }])").unwrap();
388        println!("{:?}", res);
389
390        assert_eq!(
391            res,
392            ModuleArgs::F6(def::Array(vec![
393                ModuleSubObj {
394                    imports: def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")]),
395                    global: def::Option(Some(def::Bool(true))),
396                    sub: def::Option(None)
397                },
398                ModuleSubObj {
399                    imports: def::Array(vec![def::Expr::from("Ident3"), def::Expr::from("Ident4")]),
400                    global: def::Option(None),
401                    sub: def::Option(None)
402                }
403            ]))
404        );
405    }
406
407    #[test]
408    fn test_formal_f6_3() {
409        let res = ModuleArgs::parse("F([{ imports: [Ident1, Ident2], global: true, sub: { value: true } }, { imports: [Ident3, Ident4] }])").unwrap();
410        println!("{:?}", res);
411
412        assert_eq!(
413            res,
414            ModuleArgs::F6(def::Array(vec![
415                ModuleSubObj {
416                    imports: def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")]),
417                    global: def::Option(Some(def::Bool(true))),
418                    sub: def::Option(Some(Sub { value: def::Bool(true) }))
419                },
420                ModuleSubObj {
421                    imports: def::Array(vec![def::Expr::from("Ident3"), def::Expr::from("Ident4")]),
422                    global: def::Option(None),
423                    sub: def::Option(None)
424                }
425            ]))
426        );
427    }
428    #[test]
429    fn test_formal_f7() {
430        let res = ModuleArgs::parse("F({ s1: { value: false }, s2: { value: true } })").unwrap();
431        println!("{:?}", res);
432
433        assert_eq!(res, ModuleArgs::F7(SubWrap { s1: Sub { value: def::Bool(false) }, s2: Sub { value: def::Bool(true) } }));
434    }
435
436    #[test]
437    fn test_tokens_formal_f7() {
438        let res = ModuleArgs::parse("F({ s1: { value: false }, s2: { value: true } })").unwrap();
439        println!("{:?}", res);
440
441        assert_eq!(res, ModuleArgs::F7(SubWrap { s1: Sub { value: def::Bool(false) }, s2: Sub { value: def::Bool(true) } }));
442    }
443
444    #[test]
445    fn test_formal_f8() {
446        let res = ModuleArgs::parse("F({ controllers: [Ident1, Ident2] })").unwrap();
447        println!("{:?}", res);
448
449        assert_eq!(
450            res,
451            ModuleArgs::F8(def::Option(Some(T1 {
452                controllers: def::Option(Some(def::Array(vec![def::Expr::from("Ident1"), def::Expr::from("Ident2")])))
453            })))
454        );
455
456        let res = ModuleArgs::parse("F()").unwrap();
457        println!("{:?}", res);
458
459        assert_eq!(res, ModuleArgs::F8(def::Option(None)));
460    }
461
462    // #[test]
463    fn test_value_p1() {
464        let f = Formal::new();
465
466        let args = f.parse("F(1, { a:1, b:2 })").unwrap();
467        println!("{:?}", args);
468
469        assert_eq!(
470            args.0,
471            Value::Array(def::Array(vec![
472                Value::Int(def::Int(1)),
473                Value::Object(def::Object(
474                    vec![("a".to_string(), Value::Int(def::Int(1))), ("b".to_string(), Value::Int(def::Int(2)))].into_iter().collect()
475                ))
476            ]))
477        );
478    }
479
480    #[test]
481    fn test_into_object_p1() {
482        let f = Formal::new();
483        let args = f.parse("F({ imports: [Ident1::register(), Ident2] })").unwrap();
484        println!("{:?}", args);
485        let res = ModuleSubObj::try_from(args).unwrap();
486
487        assert_eq!(
488            res,
489            ModuleSubObj {
490                imports: def::Array(vec![def::Expr::from("Ident1::register ()"), def::Expr::from("Ident2")]),
491                global: def::Option(None),
492                sub: def::Option(None)
493            }
494        );
495    }
496
497    #[test]
498    fn test_extends_p1() {
499        let f = Formal::new();
500        let args = f.parse("F(\"Hello\", true, false)").unwrap();
501        println!("{:?}", args);
502        let res = ModuleArgs::try_from(args).unwrap();
503
504        assert_eq!(res, ModuleArgs::F9(def::String("Hello".to_string()), def::Extends(vec![def::Bool(true), def::Bool(false)])));
505    }
506}