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