diff --git a/src/gen.rs b/src/gen.rs index 0222e811..328eba42 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -344,6 +344,48 @@ impl ToTokens for RumaEvent { TokenStream::new() }; + let impl_conversions_for_content = if let Content::Struct(content_fields) = &self.content { + let mut content_field_values: Vec = + Vec::with_capacity(content_fields.len()); + + for content_field in content_fields { + let content_field_ident = content_field.ident.clone().unwrap(); + let span = content_field.span(); + + let token_stream = quote_spanned! {span=> + #content_field_ident: raw.#content_field_ident, + }; + + content_field_values.push(token_stream); + } + + quote! { + impl std::str::FromStr for #content_name { + type Err = crate::InvalidEvent; + + /// Attempt to create `Self` from parsing a string of JSON data. + fn from_str(json: &str) -> Result { + let raw = serde_json::from_str::(json)?; + + Ok(Self { + #(#content_field_values)* + }) + } + } + + impl<'a> std::convert::TryFrom<&'a str> for #content_name { + type Error = crate::InvalidEvent; + + /// Attempt to create `Self` from parsing a string of JSON data. + fn try_from(json: &'a str) -> Result { + std::str::FromStr::from_str(json) + } + } + } + } else { + TokenStream::new() + }; + let output = quote!( #(#attrs)* #[derive(Clone, PartialEq, Debug)] @@ -375,6 +417,8 @@ impl ToTokens for RumaEvent { } } + #impl_conversions_for_content + use serde::ser::SerializeStruct as _; impl serde::Serialize for #name {