Convert from JSON using impl FromStr and impl TryFrom<&'a str> rather than an inherent from_str method.
This commit is contained in:
parent
e13acb4d7d
commit
d9039db8df
23
src/gen.rs
23
src/gen.rs
@ -145,7 +145,7 @@ impl ToTokens for RumaEvent {
|
||||
let event_type_field_count = if self.is_custom { 0 } else { 1 };
|
||||
let field_count = event_fields.len() + event_type_field_count;
|
||||
|
||||
let mut from_str_field_values: Vec<TokenStream> = Vec::with_capacity(event_fields.len());
|
||||
let mut try_from_field_values: Vec<TokenStream> = Vec::with_capacity(event_fields.len());
|
||||
let mut serialize_field_calls: Vec<TokenStream> = Vec::with_capacity(event_fields.len());
|
||||
|
||||
for field in event_fields {
|
||||
@ -159,7 +159,7 @@ impl ToTokens for RumaEvent {
|
||||
|
||||
let span = field.span();
|
||||
|
||||
let from_str_field_value = if ident == "content" {
|
||||
let try_from_field_value = if ident == "content" {
|
||||
match &self.content {
|
||||
Content::Struct(content_fields) => {
|
||||
let mut content_field_values: Vec<TokenStream> =
|
||||
@ -225,7 +225,7 @@ impl ToTokens for RumaEvent {
|
||||
}
|
||||
};
|
||||
|
||||
from_str_field_values.push(from_str_field_value);
|
||||
try_from_field_values.push(try_from_field_value);
|
||||
|
||||
let serialize_field_call = quote_spanned! {span=>
|
||||
state.serialize_field(#ident_str, &self.#ident)?;
|
||||
@ -316,17 +316,28 @@ impl ToTokens for RumaEvent {
|
||||
|
||||
#content
|
||||
|
||||
impl #name {
|
||||
impl std::str::FromStr for #name {
|
||||
type Err = crate::InvalidEvent;
|
||||
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
pub fn from_str(json: &str) -> Result<Self, crate::InvalidEvent> {
|
||||
fn from_str(json: &str) -> Result<Self, Self::Err> {
|
||||
let raw = serde_json::from_str::<raw::#name>(json)?;
|
||||
|
||||
Ok(Self {
|
||||
#(#from_str_field_values)*
|
||||
#(#try_from_field_values)*
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a str> for #name {
|
||||
type Error = crate::InvalidEvent;
|
||||
|
||||
/// Attempt to create `Self` from parsing a string of JSON data.
|
||||
fn try_from(json: &'a str) -> Result<Self, Self::Error> {
|
||||
std::str::FromStr::from_str(json)
|
||||
}
|
||||
}
|
||||
|
||||
use serde::ser::SerializeStruct as _;
|
||||
|
||||
impl serde::Serialize for #name {
|
||||
|
13
src/lib.rs
13
src/lib.rs
@ -121,11 +121,14 @@ mod parse;
|
||||
/// the first.
|
||||
///
|
||||
/// The event type and content type will have copies generated inside a private `raw` module. These
|
||||
/// "raw" versions are the same, except they implement `serde::Deserialize`. An inherent method
|
||||
/// called `from_str` will be generated for the event type that takes a `&str` of JSON and attempts
|
||||
/// to deserialize the type using the "raw" version. If deserialization fails, an error is returned
|
||||
/// to the user. If deserialization succeeds, a value of the public event type will be populated
|
||||
/// from the raw version's fields and returned.
|
||||
/// "raw" versions are the same, except they implement `serde::Deserialize`. An implementation of
|
||||
/// `TryFrom<&str>` will be provided, which (through a blanket implementation in the standard
|
||||
/// library for `FromStr` will allow the user to call `parse` on a string slice of JSON data in
|
||||
/// attempt to convert into the event type. `TryFrom<&str>` attempts to deserialize the type using
|
||||
/// the "raw" version. If deserialization fails, an error is returned to the user. If
|
||||
/// deserialization succeeds, a value of the public event type will be populated from the raw
|
||||
/// version's fields and returned. If any semantic error is found after deserialization, a
|
||||
/// `serde_json::Value` of the deserialized data will be returned in an `InvalidEvent`.
|
||||
#[proc_macro]
|
||||
pub fn ruma_event(input: TokenStream) -> TokenStream {
|
||||
let ruma_event_input = syn::parse_macro_input!(input as RumaEventInput);
|
||||
|
Loading…
x
Reference in New Issue
Block a user