1use proc_macro2::Group;
2use syn::{
3 parse::{Parse, ParseStream},
4 token::{Brace, Bracket, Paren},
5 Expr, Ident, Lit, Token,
6};
7
8use crate::utils::{recursive_lit, recursive_parsing};
9use crate::{def, Value};
10
11#[derive(Debug)]
30pub struct SynArgs {
31 pub value: Value,
32}
33
34impl SynArgs {
35 pub fn arguments<T: TryFrom<Value, Error = syn::Error>>(self) -> Result<T, syn::Error> {
36 T::try_from(self.value)
37 }
38}
39
40impl Parse for SynArgs {
41 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
42 let mut res: Vec<Value> = vec![];
43
44 if input.peek(Ident) && input.peek2(Paren) {
45 input.parse::<Ident>()?;
46 }
47
48 if input.peek(Paren) {
49 let group = input.parse::<Group>()?;
50 let stream = group.stream();
51 return syn::parse2(stream);
52 }
53
54 let content = input;
55
56 while !content.is_empty() {
57 if content.peek(Lit) {
58 let lit = content.parse::<Lit>()?;
59 res.push(recursive_lit(&lit));
60 } else if content.peek(Brace) {
61 let group: ObjectArgs = content.parse()?;
62 res.push(Value::Object(def::Object(group.value)));
63 } else if content.peek(Bracket) {
64 let group: ArrayArgs = content.parse()?;
65 res.push(Value::Array(def::Array(group.value)));
66 } else if let Ok(v) = content.parse::<syn::Expr>() {
67 res.push(recursive_parsing(&v));
68 } else {
69 println!("Failed to parse: {:?}", content);
70 }
71
72 if content.is_empty() {
73 break;
74 }
75 let _ = content.parse::<Token![,]>()?;
76 }
77
78 Ok(SynArgs { value: Value::Array(def::Array(res)) })
79 }
80}
81
82pub(crate) struct ObjectArgs {
83 pub value: std::collections::HashMap<String, Value>,
84}
85
86impl Parse for ObjectArgs {
87 fn parse(input: ParseStream) -> syn::Result<Self> {
88 let content;
89 let _ = syn::braced!(content in input);
90
91 let mut value = std::collections::HashMap::new();
92
93 while !content.is_empty() {
94 let key: Ident = content.parse()?;
95 let _: Token![:] = content.parse()?;
96 if content.peek(Brace) {
97 let group: ObjectArgs = content.parse()?;
98 value.insert(key.to_string(), Value::Object(def::Object(group.value)));
99 } else {
100 let expr = content.parse::<Expr>()?;
101 value.insert(key.to_string(), recursive_parsing(&expr));
102 }
103 if content.is_empty() {
104 break;
105 }
106 let _: Token![,] = content.parse()?;
107 }
108
109 Ok(ObjectArgs { value })
110 }
111}
112
113pub(crate) struct ArrayArgs {
114 pub value: Vec<Value>,
115}
116
117impl Parse for ArrayArgs {
118 fn parse(input: ParseStream) -> syn::Result<Self> {
119 let content;
120 let _ = syn::bracketed!(content in input);
121
122 let mut value = vec![];
123
124 while !content.is_empty() {
125 let p = content.parse::<SynArgs>()?;
126
127 if let Value::Array(def::Array(v)) = p.value {
128 value.extend(v);
129 }
130
131 if content.is_empty() {
132 break;
133 }
134 let _: Token![,] = content.parse()?;
135 }
136
137 Ok(ArrayArgs { value })
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn test_syn_args() {
147 let args = syn::parse_str::<SynArgs>("(1, 20, { a: 12 })").unwrap();
148 assert_eq!(format!("{:?}", args.value), "Array(Array([Int(Int(1)), Int(Int(20)), Object(Object({\"a\": Int(Int(12))}))]))");
149 }
150
151 #[test]
152 fn test_syn_args2() {
153 let args = syn::parse_str::<SynArgs>("(Test, MY::TEST)").unwrap();
154 assert_eq!(format!("{:?}", args.value), "Array(Array([Expr(Expr(\"Test\")), Expr(Expr(\"MY :: TEST\"))]))");
155 }
156
157 #[test]
158 fn test_syn_args3() {
159 let args = syn::parse_str::<SynArgs>("([Test, MY::TEST])").unwrap();
160 assert_eq!(format!("{:?}", args.value), "Array(Array([Array(Array([Expr(Expr(\"Test\")), Expr(Expr(\"MY :: TEST\"))]))]))");
161 }
162
163 #[test]
164 fn test_syn_args3_no_parenthesized() {
165 let args = syn::parse_str::<SynArgs>("[Test, MY::TEST]").unwrap();
166 assert_eq!(format!("{:?}", args.value), "Array(Array([Array(Array([Expr(Expr(\"Test\")), Expr(Expr(\"MY :: TEST\"))]))]))");
167 }
168}