From f3de311408ee6082e40c4ea3ff72856ca894d1ce Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Tue, 19 Sep 2023 23:37:34 +0200 Subject: [PATCH] add DocCommentCode, SerdeCode, StructPropCode --- .../autorust/codegen/src/codegen_models.rs | 112 ++++++++++++++---- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/services/autorust/codegen/src/codegen_models.rs b/services/autorust/codegen/src/codegen_models.rs index f9e5243b24..3ad7b31795 100644 --- a/services/autorust/codegen/src/codegen_models.rs +++ b/services/autorust/codegen/src/codegen_models.rs @@ -519,7 +519,7 @@ fn create_enum( for enum_value in &enum_values { let value = &enum_value.value; let nm = value.to_camel_case_ident()?; - let doc_comment = DocCommentCode::new(&enum_value.description); + let doc_comment = DocCommentCode::from(&enum_value.description); let lower = value.to_lowercase(); let rename = if &nm.to_string() == value { quote! {} @@ -637,7 +637,7 @@ fn create_enum( quote! {} }; - let doc_comment = DocCommentCode::new(&property.schema.common.description); + let doc_comment = DocCommentCode::from(&property.schema.common.description); let code = quote! { #doc_comment @@ -683,7 +683,7 @@ pub struct StructCode { doc_comment: DocCommentCode, struct_name_code: Ident, default_code: TokenStream, - props: TokenStream, + props: Vec, continuable: TokenStream, implement_default: bool, new_fn_params: Vec, @@ -712,7 +712,7 @@ impl ToTokens for StructCode { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #default_code pub struct #struct_name_code { - #props + #(#props)* } #continuable }; @@ -757,7 +757,7 @@ fn create_struct( mut needs_boxing: HashSet, ) -> Result { let mut mod_code = TokenStream::new(); - let mut props = TokenStream::new(); + let mut props = Vec::new(); let mut new_fn_params: Vec = Vec::new(); let mut new_fn_body = TokenStream::new(); let ns = struct_name.to_snake_case_ident()?; @@ -771,9 +771,11 @@ fn create_struct( let schema_name = schema.name()?; let type_name = schema_name.to_camel_case_ident()?; let field_name = schema_name.to_snake_case_ident()?; - props.extend(quote! { - #[serde(flatten)] - pub #field_name: #type_name, + props.push(StructPropCode { + doc_comments: Vec::new(), + serde: SerdeCode::flatten(), + field_name: field_name.clone(), + field_type: type_name.clone().into(), }); if schema.implement_default() { new_fn_body.extend(quote! { #field_name: #type_name::default(), }); @@ -812,9 +814,10 @@ fn create_struct( needs_boxing.clone(), )?; mod_code.extend(field_code.into_token_stream()); + let mut doc_comments = Vec::new(); // uncomment the next two lines to help identify entries that need boxed // let prop_nm_str = format!("{} , {} , {}", prop_nm.file_path, prop_nm.schema_name, property_name); - // props.extend(quote! { #[doc = #prop_nm_str ]}); + // doc_comments.push(DocCommentCode::from(&Some(prop_nm_str))); let mut boxed = false; if needs_boxing.contains(&type_name.to_string().to_camel_case_ident()?.to_string()) { @@ -869,11 +872,7 @@ fn create_struct( serde_attrs.push(quote! { with = "azure_core::xml::text_content"}); } } - let serde = if !serde_attrs.is_empty() { - quote! { #[serde(#(#serde_attrs),*)] } - } else { - quote! {} - }; + let serde = SerdeCode::new(serde_attrs); // see if a field should be wrapped in a Box if cg.should_box_property(prop_nm) { @@ -881,12 +880,13 @@ fn create_struct( } type_name = type_name.boxed(boxed); - let doc_comment = DocCommentCode::new(&property.schema.schema.common.description); + doc_comments.push(DocCommentCode::from(&property.schema.schema.common.description)); - props.extend(quote! { - #doc_comment - #serde - pub #field_name: #type_name, + props.push(StructPropCode { + doc_comments, + serde, + field_name: field_name.clone(), + field_type: type_name.clone(), }); if is_required { @@ -910,7 +910,7 @@ fn create_struct( quote! {} }; - let doc_comment = DocCommentCode::new(&schema.schema.common.description); + let doc_comment = DocCommentCode::from(&schema.schema.common.description); let mut continuable = quote! {}; if let Some(pageable) = pageable { @@ -988,12 +988,80 @@ fn create_struct( }) } +pub struct StructPropCode { + pub doc_comments: Vec, + pub serde: SerdeCode, + pub field_name: Ident, + pub field_type: TypeNameCode, +} + +impl StructPropCode { + pub fn new(field_name: Ident, field_type: TypeNameCode) -> Self { + Self { + doc_comments: Vec::new(), + serde: SerdeCode::default(), + field_name, + field_type, + } + } +} + +impl ToTokens for StructPropCode { + fn to_tokens(&self, tokens: &mut TokenStream) { + let doc_comments = &self.doc_comments; + let serde = &self.serde; + let field_name = &self.field_name; + let field_type = &self.field_type; + tokens.extend(quote! { + #(#doc_comments)* + #serde + pub #field_name: #field_type, + }); + } +} + +#[derive(Default)] +pub struct SerdeCode { + pub attributes: Vec, +} + +impl SerdeCode { + pub fn new(attributes: Vec) -> Self { + Self { attributes } + } + pub fn flatten() -> Self { + Self { + attributes: vec![quote! { flatten }], + } + } +} + +impl ToTokens for SerdeCode { + fn to_tokens(&self, tokens: &mut TokenStream) { + let attributes = &self.attributes; + if !attributes.is_empty() { + tokens.extend(quote! { + #[serde(#(#attributes),*)] + }); + } + } +} + +#[derive(Default)] pub struct DocCommentCode { description: Option, } -impl DocCommentCode { - pub fn new(description: &Option) -> Self { +impl From<&str> for DocCommentCode { + fn from(description: &str) -> Self { + Self { + description: Some(description.to_string()), + } + } +} + +impl From<&Option> for DocCommentCode { + fn from(description: &Option) -> Self { Self { description: description.clone(), }