1
1
// TODO: CLEAN ALL THIS SHIT UP WHAT THE FUCK IS THIS
2
2
3
3
use crate :: bail;
4
+ use owo_colors:: { OwoColorize , Stream , Style } ;
4
5
use proc_macro2:: TokenStream ;
5
6
use quote:: { format_ident, quote} ;
6
- use std:: borrow:: Cow ;
7
+ use std:: {
8
+ borrow:: Cow ,
9
+ fmt:: Display ,
10
+ io:: { self , Write as _} ,
11
+ } ;
7
12
use syn:: { DataEnum , DataStruct , DataUnion , DeriveInput , Lit } ;
8
13
14
+ fn print_warning ( title : impl Display , content : impl Display ) -> io:: Result < ( ) > {
15
+ let mut sink = io:: stderr ( ) ;
16
+
17
+ macro_rules! apply_style {
18
+ ( $style: ident => $content: expr) => { {
19
+ //$content.if_supports_color(Stream::Stderr, |txt| txt.style($style))
20
+ $content. style( $style)
21
+ } } ;
22
+ }
23
+
24
+ let bold_yellow = Style :: new ( ) . bold ( ) . yellow ( ) ;
25
+ let bold = Style :: new ( ) . bold ( ) ;
26
+ let blue = Style :: new ( ) . blue ( ) ;
27
+
28
+ write ! ( sink, "{}" , apply_style!( bold_yellow => "warning" ) ) ?;
29
+ writeln ! ( sink, "{}" , apply_style!( bold => format_args!( ": {title}" ) ) ) ?;
30
+
31
+ writeln ! ( sink, "{}" , apply_style!( blue => " | " ) ) ?;
32
+ write ! ( sink, "{}" , apply_style!( blue => " | " ) ) ?;
33
+ writeln ! ( sink, "{content}" ) ?;
34
+
35
+ Ok ( ( ) )
36
+ }
37
+
9
38
type Converter = fn ( & str ) -> String ;
10
39
11
40
fn case_converter ( case : & syn:: LitStr ) -> syn:: Result < Converter > {
@@ -32,11 +61,13 @@ fn case_converter(case: &syn::LitStr) -> syn::Result<Converter> {
32
61
Ok ( converter)
33
62
}
34
63
64
+ #[ inline]
35
65
fn maybe_case_converter ( case : Option < & syn:: LitStr > ) -> syn:: Result < Converter > {
36
66
case. map ( case_converter)
37
67
. unwrap_or_else ( || Ok ( |txt : & str | txt. to_string ( ) ) )
38
68
}
39
69
70
+ #[ inline]
40
71
fn ident_adapter ( converter : Converter ) -> impl Fn ( & syn:: Ident ) -> syn:: Ident {
41
72
move |ident : & syn:: Ident | format_ident ! ( "{}" , converter( & ident. to_string( ) ) )
42
73
}
@@ -63,6 +94,18 @@ impl SerdeContainerOptions {
63
94
} else if meta. path . is_ident ( "untagged" ) {
64
95
options. untagged = true ;
65
96
} else {
97
+ print_warning (
98
+ "unknown serde attribute" ,
99
+ format ! (
100
+ "unknown attribute \" {}\" " ,
101
+ meta. path
102
+ . get_ident( )
103
+ . map( |ident| ident. to_string( ) )
104
+ . unwrap_or_else( || "[error]" . into( ) )
105
+ ) ,
106
+ )
107
+ . unwrap ( ) ;
108
+
66
109
// TODO: support other serde attributes
67
110
//
68
111
// For now we simply clear the buffer to avoid errors
@@ -118,6 +161,51 @@ impl ContainerOptions {
118
161
}
119
162
}
120
163
164
+ struct SerdeFieldOptions {
165
+ rename : Option < syn:: LitStr > ,
166
+ }
167
+
168
+ impl SerdeFieldOptions {
169
+ fn parse ( attributes : & [ syn:: Attribute ] ) -> syn:: Result < Self > {
170
+ let mut options = SerdeFieldOptions { rename : None } ;
171
+
172
+ for attribute in attributes
173
+ . iter ( )
174
+ . filter ( |attr| attr. path ( ) . is_ident ( "serde" ) )
175
+ {
176
+ attribute. parse_nested_meta ( |meta| {
177
+ if meta. path . is_ident ( "rename" ) {
178
+ options. rename = Some ( meta. value ( ) ?. parse ( ) ?) ;
179
+ } else {
180
+ print_warning (
181
+ "unknown serde attribute" ,
182
+ format ! (
183
+ "unknown attribute \" {}\" " ,
184
+ meta. path
185
+ . get_ident( )
186
+ . map( |ident| ident. to_string( ) )
187
+ . unwrap_or_else( || "[error]" . into( ) )
188
+ ) ,
189
+ )
190
+ . unwrap ( ) ;
191
+
192
+ // TODO: support other serde attributes
193
+ //
194
+ // For now we simply clear the buffer to avoid errors
195
+ let _ = meta
196
+ . value ( )
197
+ . map ( |val| val. parse :: < TokenStream > ( ) . unwrap ( ) )
198
+ . unwrap_or_else ( |_| meta. input . cursor ( ) . token_stream ( ) ) ;
199
+ }
200
+
201
+ Ok ( ( ) )
202
+ } ) ?;
203
+ }
204
+
205
+ Ok ( options)
206
+ }
207
+ }
208
+
121
209
#[ inline]
122
210
fn normalize_option < T : quote:: ToTokens > ( value : Option < T > ) -> TokenStream {
123
211
match value {
@@ -154,10 +242,10 @@ fn extract_documentation(attributes: &[syn::Attribute]) -> syn::Result<Option<St
154
242
Ok ( Some ( docs) )
155
243
}
156
244
157
- fn patch_type_params < ' a > (
158
- options : & ContainerOptions ,
159
- type_params : impl Iterator < Item = & ' a mut syn:: TypeParam > ,
160
- ) {
245
+ fn patch_type_params < ' a , I > ( options : & ContainerOptions , type_params : I )
246
+ where
247
+ I : Iterator < Item = & ' a mut syn:: TypeParam > ,
248
+ {
161
249
let crate_path = & options. crate_path ;
162
250
163
251
for param in type_params {
@@ -371,7 +459,6 @@ fn expand_union(_meta: ContainerMeta, input: DataUnion) -> syn::Result<TokenStre
371
459
pub fn expand ( input : DeriveInput ) -> syn:: Result < TokenStream > {
372
460
let options = ContainerOptions :: parse ( & input. attrs ) ?;
373
461
let serde_options = SerdeContainerOptions :: parse ( & input. attrs ) ?;
374
-
375
462
let description = extract_documentation ( & input. attrs ) ?;
376
463
377
464
let meta = ContainerMeta {
0 commit comments