events: Fix serde of event types with suffix
This commit is contained in:
parent
20b8c298d2
commit
abf735093c
@ -101,7 +101,7 @@ mod tests {
|
|||||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||||
|
|
||||||
use super::{PassPhrase, SecretEncryptionAlgorithm, SecretStorageKeyEventContent};
|
use super::{PassPhrase, SecretEncryptionAlgorithm, SecretStorageKeyEventContent};
|
||||||
use crate::{serde::Base64, KeyDerivationAlgorithm};
|
use crate::{events::GlobalAccountDataEvent, serde::Base64, KeyDerivationAlgorithm};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_key_description_serialization() {
|
fn test_key_description_serialization() {
|
||||||
@ -218,4 +218,62 @@ mod tests {
|
|||||||
&& bits == uint!(256)
|
&& bits == uint!(256)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_event_serialization() {
|
||||||
|
let event = GlobalAccountDataEvent {
|
||||||
|
content: SecretStorageKeyEventContent::new(
|
||||||
|
"my_key_id".into(),
|
||||||
|
"my_key".into(),
|
||||||
|
SecretEncryptionAlgorithm::SecretStorageV1AesHmacSha2 {
|
||||||
|
iv: Base64::parse("YWJjZGVmZ2hpamtsbW5vcA").unwrap(),
|
||||||
|
mac: Base64::parse("aWRvbnRrbm93d2hhdGFtYWNsb29rc2xpa2U").unwrap(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json = json!({
|
||||||
|
"type": "m.secret_storage.key.my_key_id",
|
||||||
|
"content": {
|
||||||
|
"name": "my_key",
|
||||||
|
"algorithm": "m.secret_storage.v1.aes-hmac-sha2",
|
||||||
|
"iv": "YWJjZGVmZ2hpamtsbW5vcA",
|
||||||
|
"mac": "aWRvbnRrbm93d2hhdGFtYWNsb29rc2xpa2U"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(to_json_value(&event).unwrap(), json);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_event_deserialization() {
|
||||||
|
let json = json!({
|
||||||
|
"type": "m.secret_storage.key.my_key_id",
|
||||||
|
"content": {
|
||||||
|
"name": "my_key",
|
||||||
|
"algorithm": "m.secret_storage.v1.aes-hmac-sha2",
|
||||||
|
"iv": "YWJjZGVmZ2hpamtsbW5vcA",
|
||||||
|
"mac": "aWRvbnRrbm93d2hhdGFtYWNsb29rc2xpa2U"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
from_json_value(json).unwrap(),
|
||||||
|
GlobalAccountDataEvent {
|
||||||
|
content: SecretStorageKeyEventContent {
|
||||||
|
key_id,
|
||||||
|
name,
|
||||||
|
algorithm: SecretEncryptionAlgorithm::SecretStorageV1AesHmacSha2 {
|
||||||
|
iv,
|
||||||
|
mac,
|
||||||
|
},
|
||||||
|
passphrase: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if key_id == *"my_key_id"
|
||||||
|
&& name == *"my_key"
|
||||||
|
&& iv == Base64::parse("YWJjZGVmZ2hpamtsbW5vcA").unwrap()
|
||||||
|
&& mac == Base64::parse("aWRvbnRrbm93d2hhdGFtYWNsb29rc2xpa2U").unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,13 +483,10 @@ fn generate_event_content_impl<'a>(
|
|||||||
|
|
||||||
let (event_type_ty_decl, event_type_ty, event_type_fn_impl);
|
let (event_type_ty_decl, event_type_ty, event_type_fn_impl);
|
||||||
|
|
||||||
match event_kind {
|
let type_suffix_data = event_type
|
||||||
Some(kind) => {
|
.value()
|
||||||
let i = kind.to_event_type_enum();
|
.strip_suffix('*')
|
||||||
event_type_ty_decl = None;
|
.map(|type_prefix| {
|
||||||
event_type_ty = quote! { #ruma_common::events::#i };
|
|
||||||
event_type_fn_impl = match event_type.value().strip_suffix(".*") {
|
|
||||||
Some(type_prefix) => {
|
|
||||||
let type_fragment_field = fields
|
let type_fragment_field = fields
|
||||||
.find_map(|f| {
|
.find_map(|f| {
|
||||||
f.attrs.iter().filter(|a| a.path.is_ident("ruma_event")).find_map(|a| {
|
f.attrs.iter().filter(|a| a.path.is_ident("ruma_event")).find_map(|a| {
|
||||||
@ -500,9 +497,7 @@ fn generate_event_content_impl<'a>(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?
|
||||||
|
|
||||||
let f = type_fragment_field
|
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
syn::Error::new_spanned(
|
syn::Error::new_spanned(
|
||||||
event_type,
|
event_type,
|
||||||
@ -514,10 +509,21 @@ fn generate_event_content_impl<'a>(
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("type fragment field needs to have a name");
|
.expect("type fragment field needs to have a name");
|
||||||
|
|
||||||
let format = type_prefix.to_owned() + ".{}";
|
<syn::Result<_>>::Ok((type_prefix.to_owned(), type_fragment_field))
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
|
match event_kind {
|
||||||
|
Some(kind) => {
|
||||||
|
let i = kind.to_event_type_enum();
|
||||||
|
event_type_ty_decl = None;
|
||||||
|
event_type_ty = quote! { #ruma_common::events::#i };
|
||||||
|
event_type_fn_impl = match &type_suffix_data {
|
||||||
|
Some((type_prefix, type_fragment_field)) => {
|
||||||
|
let format = type_prefix.to_owned() + "{}";
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
::std::convert::From::from(::std::format!(#format, self.#f))
|
::std::convert::From::from(::std::format!(#format, self.#type_fragment_field))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => quote! { ::std::convert::From::from(#event_type) },
|
None => quote! { ::std::convert::From::from(#event_type) },
|
||||||
@ -559,6 +565,31 @@ fn generate_event_content_impl<'a>(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let from_parts_fn_impl = if let Some((type_prefix, type_fragment_field)) = &type_suffix_data {
|
||||||
|
quote! {
|
||||||
|
if let Some(type_fragment) = ev_type.strip_prefix(#type_prefix) {
|
||||||
|
let mut content: Self = #serde_json::from_str(content.get())?;
|
||||||
|
content.#type_fragment_field = type_fragment.to_owned();
|
||||||
|
|
||||||
|
::std::result::Result::Ok(content)
|
||||||
|
} else {
|
||||||
|
::std::result::Result::Err(#serde::de::Error::custom(
|
||||||
|
::std::format!("expected event type starting with `{}`, found `{}`", #type_prefix, ev_type)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
if ev_type != #event_type {
|
||||||
|
return ::std::result::Result::Err(#serde::de::Error::custom(
|
||||||
|
::std::format!("expected event type `{}`, found `{}`", #event_type, ev_type)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#serde_json::from_str(content.get())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#event_type_ty_decl
|
#event_type_ty_decl
|
||||||
|
|
||||||
@ -574,13 +605,7 @@ fn generate_event_content_impl<'a>(
|
|||||||
ev_type: &::std::primitive::str,
|
ev_type: &::std::primitive::str,
|
||||||
content: &#serde_json::value::RawValue,
|
content: &#serde_json::value::RawValue,
|
||||||
) -> #serde_json::Result<Self> {
|
) -> #serde_json::Result<Self> {
|
||||||
if ev_type != #event_type {
|
#from_parts_fn_impl
|
||||||
return ::std::result::Result::Err(#serde::de::Error::custom(
|
|
||||||
::std::format!("expected event type `{}`, found `{}`", #event_type, ev_type)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#serde_json::from_str(content.get())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ fn generate_enum(
|
|||||||
let ev_type = &e.ev_type;
|
let ev_type = &e.ev_type;
|
||||||
|
|
||||||
Ok(if let Some(prefix) = ev_type.value().strip_suffix(".*") {
|
Ok(if let Some(prefix) = ev_type.value().strip_suffix(".*") {
|
||||||
let fstr = prefix.to_owned() + "{}";
|
let fstr = prefix.to_owned() + ".{}";
|
||||||
quote! { #start(_s) => ::std::borrow::Cow::Owned(::std::format!(#fstr, _s)) }
|
quote! { #start(_s) => ::std::borrow::Cow::Owned(::std::format!(#fstr, _s)) }
|
||||||
} else {
|
} else {
|
||||||
quote! { #start => ::std::borrow::Cow::Borrowed(#ev_type) }
|
quote! { #start => ::std::borrow::Cow::Borrowed(#ev_type) }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user