1
- use std:: borrow:: Cow ;
2
-
3
1
use crate :: bail;
4
2
use proc_macro2:: TokenStream ;
5
3
use quote:: quote;
6
- use syn:: { punctuated:: Punctuated , DataEnum , DataStruct , DataUnion , DeriveInput , Lit } ;
4
+ use std:: borrow:: Cow ;
5
+ use syn:: { DataEnum , DataStruct , DataUnion , DeriveInput , Lit } ;
7
6
8
7
struct SerdeContainerOptions {
9
8
rename_all : Option < syn:: LitStr > ,
@@ -45,12 +44,16 @@ impl SerdeContainerOptions {
45
44
}
46
45
47
46
struct ContainerOptions {
47
+ r#as : Option < syn:: Ident > ,
48
+ r#type : Option < syn:: Expr > ,
48
49
crate_path : syn:: Path ,
49
50
}
50
51
51
52
impl ContainerOptions {
52
53
fn parse ( attributes : & [ syn:: Attribute ] ) -> syn:: Result < Self > {
53
54
let mut options = ContainerOptions {
55
+ r#as : None ,
56
+ r#type : None ,
54
57
crate_path : syn:: parse_str ( "::cw_schema" ) ?,
55
58
} ;
56
59
@@ -62,6 +65,10 @@ impl ContainerOptions {
62
65
if meta. path . is_ident ( "crate" ) {
63
66
let stringified: syn:: LitStr = meta. value ( ) ?. parse ( ) ?;
64
67
options. crate_path = stringified. parse ( ) ?;
68
+ } else if meta. path . is_ident ( "as" ) {
69
+ options. r#as = Some ( meta. value ( ) ?. parse ( ) ?) ;
70
+ } else if meta. path . is_ident ( "type" ) {
71
+ options. r#type = Some ( meta. value ( ) ?. parse ( ) ?) ;
65
72
} else {
66
73
bail ! ( meta. path, "unknown attribute" ) ;
67
74
}
@@ -228,55 +235,72 @@ fn expand_struct(mut meta: ContainerMeta, input: DataStruct) -> syn::Result<Toke
228
235
let description = normalize_option ( meta. description . as_ref ( ) ) ;
229
236
let crate_path = & meta. options . crate_path ;
230
237
231
- let node_ty = match input. fields {
232
- syn:: Fields :: Named ( named) => {
233
- let items = named. named . iter ( ) . map ( |field| {
234
- let name = field. ident . as_ref ( ) . unwrap ( ) ;
235
- let description = normalize_option ( extract_documentation ( & field. attrs ) ?) ;
236
- let field_ty = & field. ty ;
237
-
238
- let expanded = quote ! {
239
- (
240
- stringify!( #name) . into( ) ,
241
- #crate_path:: StructProperty {
242
- description: #description,
243
- value: <#field_ty as #crate_path:: Schemaifier >:: visit_schema( visitor) ,
244
- }
245
- )
246
- } ;
247
-
248
- Ok ( expanded)
249
- } ) . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
250
-
238
+ let node = if let Some ( ref r#as) = meta. options . r#as {
239
+ quote ! {
240
+ let definition_resource = #crate_path:: Schemaifier :: visit_schema( visitor) ;
241
+ visitor. get_schema:: <#r#as>( ) . unwrap( ) . clone( )
242
+ }
243
+ } else {
244
+ let node_ty = if let Some ( ref r#type) = meta. options . r#type {
251
245
quote ! {
252
- #crate_path:: StructType :: Named {
253
- properties: #crate_path:: reexport:: BTreeMap :: from( [
254
- #( #items, ) *
255
- ] )
256
- }
246
+ #r#type
257
247
}
258
- }
259
- syn:: Fields :: Unnamed ( fields) => {
260
- let type_names = fields. unnamed . iter ( ) . map ( |field| & field. ty ) ;
248
+ } else {
249
+ let node_ty = match input. fields {
250
+ syn:: Fields :: Named ( named) => {
251
+ let items = named. named . iter ( ) . map ( |field| {
252
+ let name = field. ident . as_ref ( ) . unwrap ( ) ;
253
+ let description = normalize_option ( extract_documentation ( & field. attrs ) ?) ;
254
+ let field_ty = & field. ty ;
255
+
256
+ let expanded = quote ! {
257
+ (
258
+ stringify!( #name) . into( ) ,
259
+ #crate_path:: StructProperty {
260
+ description: #description,
261
+ value: <#field_ty as #crate_path:: Schemaifier >:: visit_schema( visitor) ,
262
+ }
263
+ )
264
+ } ;
265
+
266
+ Ok ( expanded)
267
+ } ) . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
268
+
269
+ quote ! {
270
+ #crate_path:: StructType :: Named {
271
+ properties: #crate_path:: reexport:: BTreeMap :: from( [
272
+ #( #items, ) *
273
+ ] )
274
+ }
275
+ }
276
+ }
277
+ syn:: Fields :: Unnamed ( fields) => {
278
+ let type_names = fields. unnamed . iter ( ) . map ( |field| & field. ty ) ;
279
+
280
+ quote ! {
281
+ #crate_path:: StructType :: Tuple {
282
+ items: vec![
283
+ #(
284
+ <#type_names as #crate_path:: Schemaifier >:: visit_schema( visitor) ,
285
+ ) *
286
+ ] ,
287
+ }
288
+ }
289
+ }
290
+ syn:: Fields :: Unit => quote ! { #crate_path:: StructType :: Unit } ,
291
+ } ;
261
292
262
293
quote ! {
263
- #crate_path:: StructType :: Tuple {
264
- items: vec![
265
- #(
266
- <#type_names as #crate_path:: Schemaifier >:: visit_schema( visitor) ,
267
- ) *
268
- ] ,
269
- }
294
+ #crate_path:: NodeType :: Struct ( #node_ty)
270
295
}
271
- }
272
- syn:: Fields :: Unit => quote ! { #crate_path:: StructType :: Unit } ,
273
- } ;
296
+ } ;
274
297
275
- let node = quote ! {
276
- #crate_path:: Node {
277
- name: std:: any:: type_name:: <Self >( ) . into( ) ,
278
- description: #description,
279
- value: #crate_path:: NodeType :: Struct ( #node_ty) ,
298
+ quote ! {
299
+ #crate_path:: Node {
300
+ name: std:: any:: type_name:: <Self >( ) . into( ) ,
301
+ description: #description,
302
+ value: #node_ty,
303
+ }
280
304
}
281
305
} ;
282
306
0 commit comments