events: Add a compat workaround for prev_content in unsigned
This commit is contained in:
		
							parent
							
								
									1907ce1e91
								
							
						
					
					
						commit
						098339056b
					
				@ -18,6 +18,9 @@ version = "0.24.3"
 | 
			
		||||
[lib]
 | 
			
		||||
proc-macro = true
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
compat = []
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
proc-macro-crate = "1.0.0"
 | 
			
		||||
proc-macro2 = "1.0.24"
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ pub fn expand_event(input: DeriveInput) -> syn::Result<TokenStream> {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let serialize_impl = expand_serialize_event(&input, &var, &fields, &ruma_events);
 | 
			
		||||
    let deserialize_impl = expand_deserialize_event(&input, &var, &fields, &ruma_events)?;
 | 
			
		||||
    let deserialize_impl = expand_deserialize_event(&input, &kind, &var, &fields, &ruma_events)?;
 | 
			
		||||
    let conversion_impl = expand_from_into(&input, &kind, &var, &fields, &ruma_events);
 | 
			
		||||
 | 
			
		||||
    let eq_impl = expand_eq_ord_event(&input, &fields);
 | 
			
		||||
@ -120,6 +120,7 @@ fn expand_serialize_event(
 | 
			
		||||
 | 
			
		||||
fn expand_deserialize_event(
 | 
			
		||||
    input: &DeriveInput,
 | 
			
		||||
    _kind: &EventKind,
 | 
			
		||||
    var: &EventKindVariation,
 | 
			
		||||
    fields: &[Field],
 | 
			
		||||
    ruma_events: &TokenStream,
 | 
			
		||||
@ -154,12 +155,30 @@ fn expand_deserialize_event(
 | 
			
		||||
            let ty = &field.ty;
 | 
			
		||||
            if name == "content" || name == "prev_content" {
 | 
			
		||||
                if is_generic {
 | 
			
		||||
                    quote! { Box<#serde_json::value::RawValue> }
 | 
			
		||||
                    quote! { ::std::boxed::Box<#serde_json::value::RawValue> }
 | 
			
		||||
                } else {
 | 
			
		||||
                    quote! { #content_type }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                quote! { #ty }
 | 
			
		||||
                #[allow(unused_mut)]
 | 
			
		||||
                let mut ty = quote! { #ty };
 | 
			
		||||
 | 
			
		||||
                #[cfg(feature = "compat")]
 | 
			
		||||
                if matches!(_kind, EventKind::State) && name == "unsigned" {
 | 
			
		||||
                    match var {
 | 
			
		||||
                        EventKindVariation::Full | EventKindVariation::Sync => {
 | 
			
		||||
                            ty = quote! { #ruma_events::UnsignedWithPrevContent };
 | 
			
		||||
                        }
 | 
			
		||||
                        EventKindVariation::Redacted | EventKindVariation::RedactedSync => {
 | 
			
		||||
                            ty = quote! { #ruma_events::RedactedUnsignedWithPrevContent };
 | 
			
		||||
                        }
 | 
			
		||||
                        EventKindVariation::Stripped
 | 
			
		||||
                        | EventKindVariation::Initial
 | 
			
		||||
                        | EventKindVariation::RedactedStripped => unreachable!(),
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ty
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .collect();
 | 
			
		||||
@ -207,16 +226,43 @@ fn expand_deserialize_event(
 | 
			
		||||
                }
 | 
			
		||||
            } else if name == "prev_content" {
 | 
			
		||||
                if is_generic {
 | 
			
		||||
                    quote! {
 | 
			
		||||
                    #[allow(unused_mut)]
 | 
			
		||||
                    let mut res = quote! {
 | 
			
		||||
                        let prev_content = prev_content.map(|json| {
 | 
			
		||||
                            C::from_parts(&event_type, &json).map_err(A::Error::custom)
 | 
			
		||||
                        }).transpose()?;
 | 
			
		||||
                    }
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    #[cfg(feature = "compat")]
 | 
			
		||||
                    if let EventKind::State = _kind {
 | 
			
		||||
                        res = quote! {
 | 
			
		||||
                            let prev_content = prev_content
 | 
			
		||||
                                .or_else(|| unsigned.as_mut().and_then(|u| u.prev_content.take()));
 | 
			
		||||
                            #res
 | 
			
		||||
                        };
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    res
 | 
			
		||||
                } else {
 | 
			
		||||
                    TokenStream::new()
 | 
			
		||||
                }
 | 
			
		||||
            } else if name == "unsigned" {
 | 
			
		||||
                quote! { let unsigned = unsigned.unwrap_or_default(); }
 | 
			
		||||
                #[allow(unused_mut)]
 | 
			
		||||
                let mut res = quote! {
 | 
			
		||||
                    let unsigned = unsigned.unwrap_or_default();
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                #[cfg(feature = "compat")]
 | 
			
		||||
                if matches!(_kind, EventKind::State) {
 | 
			
		||||
                    res = quote! {
 | 
			
		||||
                        let unsigned = unsigned.map_or_else(
 | 
			
		||||
                            ::std::default::Default::default,
 | 
			
		||||
                            ::std::convert::From::from,
 | 
			
		||||
                        );
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                res
 | 
			
		||||
            } else {
 | 
			
		||||
                let attrs: Vec<_> = field
 | 
			
		||||
                    .attrs
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ all-features = true
 | 
			
		||||
rustdoc-args = ["--cfg", "docsrs"]
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
compat = []
 | 
			
		||||
compat = ["ruma-events-macros/compat"]
 | 
			
		||||
markdown = ["pulldown-cmark"]
 | 
			
		||||
 | 
			
		||||
unstable-exhaustive-types = []
 | 
			
		||||
 | 
			
		||||
@ -194,6 +194,10 @@ pub use self::{
 | 
			
		||||
    unsigned::{RedactedUnsigned, Unsigned},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
#[cfg(feature = "compat")]
 | 
			
		||||
pub use unsigned::{RedactedUnsignedWithPrevContent, UnsignedWithPrevContent};
 | 
			
		||||
 | 
			
		||||
/// The base trait that all event content types implement.
 | 
			
		||||
///
 | 
			
		||||
/// Implementing this trait allows content types to be serialized as well as deserialized.
 | 
			
		||||
 | 
			
		||||
@ -74,3 +74,50 @@ impl RedactedUnsigned {
 | 
			
		||||
        self.redacted_because.is_none()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
#[cfg(feature = "compat")]
 | 
			
		||||
#[derive(Deserialize)]
 | 
			
		||||
pub struct UnsignedWithPrevContent {
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    age: Option<Int>,
 | 
			
		||||
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    transaction_id: Option<String>,
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "unstable-pre-spec")]
 | 
			
		||||
    #[cfg_attr(docsrs, doc(cfg(feature = "unstable-pre-spec")))]
 | 
			
		||||
    #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    relations: Option<Relations>,
 | 
			
		||||
 | 
			
		||||
    pub prev_content: Option<Box<serde_json::value::RawValue>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "compat")]
 | 
			
		||||
impl From<UnsignedWithPrevContent> for Unsigned {
 | 
			
		||||
    fn from(u: UnsignedWithPrevContent) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            age: u.age,
 | 
			
		||||
            transaction_id: u.transaction_id,
 | 
			
		||||
            #[cfg(feature = "unstable-pre-spec")]
 | 
			
		||||
            relations: u.relations,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[doc(hidden)]
 | 
			
		||||
#[cfg(feature = "compat")]
 | 
			
		||||
#[derive(Deserialize)]
 | 
			
		||||
pub struct RedactedUnsignedWithPrevContent {
 | 
			
		||||
    #[serde(skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    redacted_because: Option<Box<SyncRedactionEvent>>,
 | 
			
		||||
 | 
			
		||||
    pub prev_content: Option<Box<serde_json::value::RawValue>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "compat")]
 | 
			
		||||
impl From<RedactedUnsignedWithPrevContent> for RedactedUnsigned {
 | 
			
		||||
    fn from(u: RedactedUnsignedWithPrevContent) -> Self {
 | 
			
		||||
        Self { redacted_because: u.redacted_because }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user