From c854cb913252b01ebdbf66bf6296936d45be4784 Mon Sep 17 00:00:00 2001 From: Nikita Vilunov Date: Sat, 18 Feb 2023 18:19:46 +0100 Subject: [PATCH] Support for generic fields in structs --- yaserde/tests/generic.rs | 24 +++++++++++++++++++ yaserde_derive/src/ser/expand_enum.rs | 3 ++- yaserde_derive/src/ser/expand_struct.rs | 4 +++- .../src/ser/implement_serializer.rs | 6 ++++- yaserde_derive/src/ser/mod.rs | 3 ++- 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 yaserde/tests/generic.rs diff --git a/yaserde/tests/generic.rs b/yaserde/tests/generic.rs new file mode 100644 index 0000000..a2759f9 --- /dev/null +++ b/yaserde/tests/generic.rs @@ -0,0 +1,24 @@ +use yaserde::{serialize_and_validate, YaSerialize}; + +extern crate yaserde; +#[macro_use] +extern crate yaserde_derive; + +#[test] +fn parametrized_field() { + #[derive(Debug, PartialEq, YaSerialize)] + #[yaserde(rename = "outer")] + pub struct Outer { + pub inner: T, + } + + #[derive(Debug, PartialEq, YaSerialize)] + pub struct Inner { + #[yaserde(text)] + pub body: String, + } + + let content = "Test"; + let model = Outer { inner: Inner { body: "Test".to_owned() }}; + serialize_and_validate!(model, content); +} diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index ea97fd5..343cb38 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -2,7 +2,7 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::ser::{implement_serializer::implement_serializer, label::build_label_name}; use proc_macro2::TokenStream; use quote::quote; -use syn::DataEnum; +use syn::{DataEnum, Generics}; use syn::Fields; use syn::Ident; @@ -88,6 +88,7 @@ pub fn serialize( name, root, root_attributes, + &Generics::default(), quote!(#variant_matches), quote!(match self { #inner_enum_inspector diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 6bb5c49..a39f138 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -3,7 +3,7 @@ use crate::common::{Field, YaSerdeAttribute, YaSerdeField}; use crate::ser::{element::*, implement_serializer::implement_serializer}; use proc_macro2::TokenStream; use quote::quote; -use syn::DataStruct; +use syn::{DataStruct, Generics}; use syn::Ident; pub fn serialize( @@ -11,6 +11,7 @@ pub fn serialize( name: &Ident, root: &str, root_attributes: &YaSerdeAttribute, + generics: &Generics, ) -> TokenStream { let append_attributes: TokenStream = data_struct .fields @@ -346,6 +347,7 @@ pub fn serialize( name, root, root_attributes, + generics, append_attributes, struct_inspector, ) diff --git a/yaserde_derive/src/ser/implement_serializer.rs b/yaserde_derive/src/ser/implement_serializer.rs index da3d9ab..e7c2ebb 100644 --- a/yaserde_derive/src/ser/implement_serializer.rs +++ b/yaserde_derive/src/ser/implement_serializer.rs @@ -3,19 +3,23 @@ use crate::ser::namespace::generate_namespaces_definition; use proc_macro2::Ident; use proc_macro2::TokenStream; use quote::quote; +use syn::Generics; pub fn implement_serializer( name: &Ident, root: &str, attributes: &YaSerdeAttribute, + generics: &Generics, append_attributes: TokenStream, inner_inspector: TokenStream, ) -> TokenStream { let namespaces_definition = generate_namespaces_definition(attributes); let flatten = attributes.flatten; + let (impl_generics, type_generics, _) = generics.split_for_impl(); + quote! { - impl ::yaserde::YaSerialize for #name { + impl #impl_generics ::yaserde::YaSerialize for #name #type_generics { #[allow(unused_variables)] fn serialize( &self, diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index 98548ab..21f3c4b 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -13,6 +13,7 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result Result { - expand_struct::serialize(data_struct, name, &root_name, &root_attributes) + expand_struct::serialize(data_struct, name, &root_name, &root_attributes, generics) } syn::Data::Enum(ref data_enum) => { expand_enum::serialize(data_enum, name, &root_name, &root_attributes)