1- use std:: borrow:: Cow ;
2-
31use crate :: bail;
42use proc_macro2:: TokenStream ;
53use 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 } ;
76
87struct SerdeContainerOptions {
98 rename_all : Option < syn:: LitStr > ,
@@ -45,12 +44,16 @@ impl SerdeContainerOptions {
4544}
4645
4746struct ContainerOptions {
47+ r#as : Option < syn:: Ident > ,
48+ r#type : Option < syn:: Expr > ,
4849 crate_path : syn:: Path ,
4950}
5051
5152impl ContainerOptions {
5253 fn parse ( attributes : & [ syn:: Attribute ] ) -> syn:: Result < Self > {
5354 let mut options = ContainerOptions {
55+ r#as : None ,
56+ r#type : None ,
5457 crate_path : syn:: parse_str ( "::cw_schema" ) ?,
5558 } ;
5659
@@ -62,6 +65,10 @@ impl ContainerOptions {
6265 if meta. path . is_ident ( "crate" ) {
6366 let stringified: syn:: LitStr = meta. value ( ) ?. parse ( ) ?;
6467 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 ( ) ?) ;
6572 } else {
6673 bail ! ( meta. path, "unknown attribute" ) ;
6774 }
@@ -228,55 +235,72 @@ fn expand_struct(mut meta: ContainerMeta, input: DataStruct) -> syn::Result<Toke
228235 let description = normalize_option ( meta. description . as_ref ( ) ) ;
229236 let crate_path = & meta. options . crate_path ;
230237
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 {
251245 quote ! {
252- #crate_path:: StructType :: Named {
253- properties: #crate_path:: reexport:: BTreeMap :: from( [
254- #( #items, ) *
255- ] )
256- }
246+ #r#type
257247 }
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+ } ;
261292
262293 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)
270295 }
271- }
272- syn:: Fields :: Unit => quote ! { #crate_path:: StructType :: Unit } ,
273- } ;
296+ } ;
274297
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+ }
280304 }
281305 } ;
282306
0 commit comments