Replace EventResult with EventJson, simplify InvalidEvent
This commit is contained in:
parent
df05e88793
commit
eb3a3e2163
@ -1,7 +1,7 @@
|
|||||||
language: "rust"
|
language: "rust"
|
||||||
cache: "cargo"
|
cache: "cargo"
|
||||||
rust:
|
rust:
|
||||||
- 1.36.0
|
- 1.38.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
@ -13,7 +13,7 @@ jobs:
|
|||||||
before_script:
|
before_script:
|
||||||
- rustup component add rustfmt
|
- rustup component add rustfmt
|
||||||
- |
|
- |
|
||||||
if [ "$TRAVIS_RUST_VERSION" != "1.36.0" ]; then
|
if [ "$TRAVIS_RUST_VERSION" != "1.38.0" ]; then
|
||||||
rustup component add clippy
|
rustup component add clippy
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
@ -28,7 +28,7 @@ script:
|
|||||||
fi
|
fi
|
||||||
- cargo fmt --all -- --check
|
- cargo fmt --all -- --check
|
||||||
- |
|
- |
|
||||||
if [ "$TRAVIS_RUST_VERSION" != "1.36.0" ]; then
|
if [ "$TRAVIS_RUST_VERSION" != "1.38.0" ]; then
|
||||||
cargo clippy --all --all-targets --all-features -- -D warnings
|
cargo clippy --all --all-targets --all-features -- -D warnings
|
||||||
fi
|
fi
|
||||||
- cargo build --all --verbose
|
- cargo build --all --verbose
|
||||||
|
@ -18,7 +18,7 @@ ruma-events-macros = { path = "ruma-events-macros", version = "=0.20.0" }
|
|||||||
ruma-identifiers = "0.16.0"
|
ruma-identifiers = "0.16.0"
|
||||||
ruma-serde = "0.1.0"
|
ruma-serde = "0.1.0"
|
||||||
serde = { version = "1.0.106", features = ["derive"] }
|
serde = { version = "1.0.106", features = ["derive"] }
|
||||||
serde_json = "1.0.51"
|
serde_json = { version = "1.0.51", features = ["raw_value"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
## Minimum Rust version
|
## Minimum Rust version
|
||||||
|
|
||||||
ruma-events requires Rust 1.36.0 or later.
|
ruma-events requires Rust 1.38.0 or later.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ mod parse;
|
|||||||
/// The event type and content type will have copies generated inside a private `raw` module. These
|
/// 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 implementation of
|
/// "raw" versions are the same, except they implement `serde::Deserialize`. An implementation of
|
||||||
/// `FromRaw` will be provided, which will allow the user to deserialize the event type as
|
/// `FromRaw` will be provided, which will allow the user to deserialize the event type as
|
||||||
/// `EventResult<EventType>`.
|
/// `EventJson<EventType>`.
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn ruma_event(input: TokenStream) -> TokenStream {
|
pub fn ruma_event(input: TokenStream) -> TokenStream {
|
||||||
let ruma_event_input = syn::parse_macro_input!(input as RumaEventInput);
|
let ruma_event_input = syn::parse_macro_input!(input as RumaEventInput);
|
||||||
|
@ -28,7 +28,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::{DirectEvent, DirectEventContent};
|
use super::{DirectEvent, DirectEventContent};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization() {
|
fn serialization() {
|
||||||
@ -64,9 +64,9 @@ mod tests {
|
|||||||
"type": "m.direct"
|
"type": "m.direct"
|
||||||
});
|
});
|
||||||
|
|
||||||
let event: DirectEvent = from_json_value::<EventResult<_>>(json_data)
|
let event: DirectEvent = from_json_value::<EventJson<_>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let direct_rooms = event.content.get(&alice).unwrap();
|
let direct_rooms = event.content.get(&alice).unwrap();
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ ruma_event! {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{DummyEvent, Empty};
|
use super::{DummyEvent, Empty};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
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};
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ mod tests {
|
|||||||
"type": "m.dummy"
|
"type": "m.dummy"
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(from_json_value::<EventResult<DummyEvent>>(json)
|
assert!(from_json_value::<EventJson<DummyEvent>>(json)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,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::{IgnoredUserListEvent, IgnoredUserListEventContent};
|
use super::{IgnoredUserListEvent, IgnoredUserListEventContent};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization() {
|
fn serialization() {
|
||||||
@ -107,9 +107,9 @@ mod tests {
|
|||||||
"type": "m.ignored_user_list"
|
"type": "m.ignored_user_list"
|
||||||
});
|
});
|
||||||
|
|
||||||
let actual = from_json_value::<EventResult<IgnoredUserListEvent>>(json_data)
|
let actual = from_json_value::<EventJson<IgnoredUserListEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let expected = IgnoredUserListEvent {
|
let expected = IgnoredUserListEvent {
|
||||||
|
112
src/json.rs
Normal file
112
src/json.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::{
|
||||||
|
clone::Clone,
|
||||||
|
fmt::{self, Debug, Formatter},
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
|
use serde::{
|
||||||
|
de::{Deserialize, Deserializer},
|
||||||
|
ser::{Serialize, Serializer},
|
||||||
|
};
|
||||||
|
use serde_json::value::RawValue;
|
||||||
|
|
||||||
|
use crate::{InvalidEvent, InvalidEventKind, TryFromRaw};
|
||||||
|
|
||||||
|
/// A wrapper around `Box<RawValue>`, to be used in place of event [content] [collection] types in
|
||||||
|
/// Matrix endpoint definition to allow request and response types to contain unknown events in
|
||||||
|
/// addition to the known event(s) represented by the generic argument `Ev`.
|
||||||
|
pub struct EventJson<T> {
|
||||||
|
json: Box<RawValue>,
|
||||||
|
_ev: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> EventJson<T> {
|
||||||
|
fn new(json: Box<RawValue>) -> Self {
|
||||||
|
Self {
|
||||||
|
json,
|
||||||
|
_ev: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access the underlying `RawValue`.
|
||||||
|
pub fn json(&self) -> &RawValue {
|
||||||
|
&self.json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TryFromRaw> EventJson<T> {
|
||||||
|
/// Try to deserialize the JSON into the expected event type.
|
||||||
|
pub fn deserialize(&self) -> Result<T, InvalidEvent> {
|
||||||
|
let raw_ev: T::Raw = match serde_json::from_str(self.json.get()) {
|
||||||
|
Ok(raw) => raw,
|
||||||
|
Err(error) => {
|
||||||
|
return Err(InvalidEvent {
|
||||||
|
message: error.to_string(),
|
||||||
|
kind: InvalidEventKind::Deserialization,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match T::try_from_raw(raw_ev) {
|
||||||
|
Ok(value) => Ok(value),
|
||||||
|
Err(err) => Err(InvalidEvent {
|
||||||
|
message: err.to_string(),
|
||||||
|
kind: InvalidEventKind::Validation,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Serialize> From<&T> for EventJson<T> {
|
||||||
|
fn from(val: &T) -> Self {
|
||||||
|
let json_string = serde_json::to_string(&val).unwrap();
|
||||||
|
Self::new(RawValue::from_string(json_string).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without the `TryFromRaw` bound, this would conflict with the next impl below
|
||||||
|
// We could remove the `TryFromRaw` bound once specialization is stabilized.
|
||||||
|
impl<T: Serialize + TryFromRaw> From<T> for EventJson<T> {
|
||||||
|
fn from(val: T) -> Self {
|
||||||
|
Self::from(&val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Box<RawValue>> for EventJson<T> {
|
||||||
|
fn from(json: Box<RawValue>) -> Self {
|
||||||
|
Self::new(json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Clone for EventJson<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self::new(self.json.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Debug for EventJson<T> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
use std::any::type_name;
|
||||||
|
f.debug_struct(&format!("EventJson::<{}>", type_name::<T>()))
|
||||||
|
.field("json", &self.json)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T> Deserialize<'de> for EventJson<T> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Box::<RawValue>::deserialize(deserializer).map(Self::new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Serialize for EventJson<T> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
self.json.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
@ -318,7 +318,7 @@ mod tests {
|
|||||||
HashAlgorithm, KeyAgreementProtocol, MSasV1Content, MSasV1ContentOptions,
|
HashAlgorithm, KeyAgreementProtocol, MSasV1Content, MSasV1ContentOptions,
|
||||||
MessageAuthenticationCode, ShortAuthenticationString, StartEvent, StartEventContent,
|
MessageAuthenticationCode, ShortAuthenticationString, StartEvent, StartEventContent,
|
||||||
};
|
};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_m_sas_v1_content_missing_required_key_agreement_protocols() {
|
fn invalid_m_sas_v1_content_missing_required_key_agreement_protocols() {
|
||||||
@ -444,9 +444,9 @@ mod tests {
|
|||||||
|
|
||||||
// Deserialize the content struct separately to verify `TryFromRaw` is implemented for it.
|
// Deserialize the content struct separately to verify `TryFromRaw` is implemented for it.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<StartEventContent>>(json_data)
|
from_json_value::<EventJson<StartEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_verification_start_content
|
key_verification_start_content
|
||||||
);
|
);
|
||||||
@ -469,9 +469,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<StartEvent>>(json_data)
|
from_json_value::<EventJson<StartEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_verification_start
|
key_verification_start
|
||||||
)
|
)
|
||||||
@ -480,17 +480,16 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn deserialization_failure() {
|
fn deserialization_failure() {
|
||||||
// Ensure that invalid JSON creates a `serde_json::Error` and not `InvalidEvent`
|
// Ensure that invalid JSON creates a `serde_json::Error` and not `InvalidEvent`
|
||||||
assert!(serde_json::from_str::<EventResult<StartEventContent>>("{").is_err());
|
assert!(serde_json::from_str::<EventJson<StartEventContent>>("{").is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization_structure_mismatch() {
|
fn deserialization_structure_mismatch() {
|
||||||
// Missing several required fields.
|
// Missing several required fields.
|
||||||
let error =
|
let error = from_json_value::<EventJson<StartEventContent>>(json!({"from_device": "123"}))
|
||||||
from_json_value::<EventResult<StartEventContent>>(json!({"from_device": "123"}))
|
.unwrap()
|
||||||
.unwrap()
|
.deserialize()
|
||||||
.into_result()
|
.unwrap_err();
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert!(error.message().contains("missing field"));
|
assert!(error.message().contains("missing field"));
|
||||||
assert!(error.is_deserialization());
|
assert!(error.is_deserialization());
|
||||||
@ -508,9 +507,9 @@ mod tests {
|
|||||||
"short_authentication_string": ["decimal"]
|
"short_authentication_string": ["decimal"]
|
||||||
});
|
});
|
||||||
|
|
||||||
let error = from_json_value::<EventResult<StartEventContent>>(json_data)
|
let error = from_json_value::<EventJson<StartEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("key_agreement_protocols"));
|
assert!(error.message().contains("key_agreement_protocols"));
|
||||||
@ -528,9 +527,9 @@ mod tests {
|
|||||||
"message_authentication_codes": ["hkdf-hmac-sha256"],
|
"message_authentication_codes": ["hkdf-hmac-sha256"],
|
||||||
"short_authentication_string": ["decimal"]
|
"short_authentication_string": ["decimal"]
|
||||||
});
|
});
|
||||||
let error = from_json_value::<EventResult<StartEventContent>>(json_data)
|
let error = from_json_value::<EventJson<StartEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("hashes"));
|
assert!(error.message().contains("hashes"));
|
||||||
@ -548,9 +547,9 @@ mod tests {
|
|||||||
"message_authentication_codes": [],
|
"message_authentication_codes": [],
|
||||||
"short_authentication_string": ["decimal"]
|
"short_authentication_string": ["decimal"]
|
||||||
});
|
});
|
||||||
let error = from_json_value::<EventResult<StartEventContent>>(json_data)
|
let error = from_json_value::<EventJson<StartEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("message_authentication_codes"));
|
assert!(error.message().contains("message_authentication_codes"));
|
||||||
@ -568,9 +567,9 @@ mod tests {
|
|||||||
"message_authentication_codes": ["hkdf-hmac-sha256"],
|
"message_authentication_codes": ["hkdf-hmac-sha256"],
|
||||||
"short_authentication_string": []
|
"short_authentication_string": []
|
||||||
});
|
});
|
||||||
let error = from_json_value::<EventResult<StartEventContent>>(json_data)
|
let error = from_json_value::<EventJson<StartEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("short_authentication_string"));
|
assert!(error.message().contains("short_authentication_string"));
|
||||||
@ -592,9 +591,9 @@ mod tests {
|
|||||||
},
|
},
|
||||||
"type": "m.key.verification.start"
|
"type": "m.key.verification.start"
|
||||||
});
|
});
|
||||||
let error = from_json_value::<EventResult<StartEvent>>(json_data)
|
let error = from_json_value::<EventJson<StartEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(error.message().contains("key_agreement_protocols"));
|
assert!(error.message().contains("key_agreement_protocols"));
|
||||||
|
78
src/lib.rs
78
src/lib.rs
@ -73,16 +73,16 @@
|
|||||||
//! # Serialization and deserialization
|
//! # Serialization and deserialization
|
||||||
//!
|
//!
|
||||||
//! All concrete event types in ruma-events can be serialized via the `Serialize` trait from
|
//! All concrete event types in ruma-events can be serialized via the `Serialize` trait from
|
||||||
//! [serde](https://serde.rs/) and can be deserialized from as `EventResult<EventType>`. In order to
|
//! [serde](https://serde.rs/) and can be deserialized from as `EventJson<EventType>`. In order to
|
||||||
//! handle incoming data that may not conform to `ruma-events`' strict definitions of event
|
//! handle incoming data that may not conform to `ruma-events`' strict definitions of event
|
||||||
//! structures, deserialization will return `EventResult::Err` on error. This error covers both
|
//! structures, deserialization will return `EventJson::Err` on error. This error covers both
|
||||||
//! structurally invalid JSON data as well as structurally valid JSON that doesn't fulfill
|
//! structurally invalid JSON data as well as structurally valid JSON that doesn't fulfill
|
||||||
//! additional constraints the matrix specification defines for some event types. The error exposes
|
//! additional constraints the matrix specification defines for some event types. The error exposes
|
||||||
//! the deserialized `serde_json::Value` so that developers can still work with the received
|
//! the deserialized `serde_json::Value` so that developers can still work with the received
|
||||||
//! event data. This makes it possible to deserialize a collection of events without the entire
|
//! event data. This makes it possible to deserialize a collection of events without the entire
|
||||||
//! collection failing to deserialize due to a single invalid event. The "content" type for each
|
//! collection failing to deserialize due to a single invalid event. The "content" type for each
|
||||||
//! event also implements `Serialize` and either `TryFromRaw` (enabling usage as
|
//! event also implements `Serialize` and either `TryFromRaw` (enabling usage as
|
||||||
//! `EventResult<ContentType>` for dedicated content types) or `Deserialize` (when the content is a
|
//! `EventJson<ContentType>` for dedicated content types) or `Deserialize` (when the content is a
|
||||||
//! type alias), allowing content to be converted to and from JSON indepedently of the surrounding
|
//! type alias), allowing content to be converted to and from JSON indepedently of the surrounding
|
||||||
//! event structure, if needed.
|
//! event structure, if needed.
|
||||||
//!
|
//!
|
||||||
@ -136,6 +136,7 @@ mod macros;
|
|||||||
mod algorithm;
|
mod algorithm;
|
||||||
mod event_type;
|
mod event_type;
|
||||||
mod from_raw;
|
mod from_raw;
|
||||||
|
mod json;
|
||||||
#[doc(hidden)] // only public for external tests
|
#[doc(hidden)] // only public for external tests
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
@ -176,19 +177,18 @@ pub use self::{
|
|||||||
algorithm::Algorithm,
|
algorithm::Algorithm,
|
||||||
event_type::EventType,
|
event_type::EventType,
|
||||||
from_raw::{FromRaw, TryFromRaw},
|
from_raw::{FromRaw, TryFromRaw},
|
||||||
|
json::EventJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An event that is malformed or otherwise invalid.
|
/// An event that is malformed or otherwise invalid.
|
||||||
///
|
///
|
||||||
/// When attempting to deserialize an [`EventResult`](enum.EventResult.html), an error in the input
|
/// When attempting to deserialize an [`EventJson`](enum.EventJson.html), an error in the input
|
||||||
/// data may cause deserialization to fail, or the JSON structure may be correct, but additional
|
/// data may cause deserialization to fail, or the JSON structure may be correct, but additional
|
||||||
/// constraints defined in the matrix specification are not upheld. This type provides an error
|
/// constraints defined in the matrix specification are not upheld. This type provides an error
|
||||||
/// message and a `serde_json::Value` representation of the invalid event, as well as a flag for
|
/// message and a flag for which type of error was encountered.
|
||||||
/// which type of error was encountered.
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InvalidEvent {
|
pub struct InvalidEvent {
|
||||||
message: String,
|
message: String,
|
||||||
json: Value,
|
|
||||||
kind: InvalidEventKind,
|
kind: InvalidEventKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,11 +204,6 @@ impl InvalidEvent {
|
|||||||
self.message.clone()
|
self.message.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `serde_json::Value` representation of the invalid event.
|
|
||||||
pub fn json(&self) -> &Value {
|
|
||||||
&self.json
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether this is a deserialization error.
|
/// Returns whether this is a deserialization error.
|
||||||
pub fn is_deserialization(&self) -> bool {
|
pub fn is_deserialization(&self) -> bool {
|
||||||
self.kind == InvalidEventKind::Deserialization
|
self.kind == InvalidEventKind::Deserialization
|
||||||
@ -243,65 +238,6 @@ impl Display for InvalidInput {
|
|||||||
|
|
||||||
impl Error for InvalidInput {}
|
impl Error for InvalidInput {}
|
||||||
|
|
||||||
/// The result of deserializing an event, which may or may not be valid.
|
|
||||||
///
|
|
||||||
/// When data is successfully deserialized and validated, this structure will contain the
|
|
||||||
/// deserialized value `T`. When deserialization succeeds, but the event is invalid for any reason,
|
|
||||||
/// this structure will contain an [`InvalidEvent`](struct.InvalidEvent.html). See the documentation
|
|
||||||
/// for [`InvalidEvent`](struct.InvalidEvent.html) for more details.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum EventResult<T: TryFromRaw> {
|
|
||||||
/// `T` deserialized and validated successfully.
|
|
||||||
Ok(T),
|
|
||||||
|
|
||||||
/// `T` failed either deserialization or validation.
|
|
||||||
///
|
|
||||||
/// [`InvalidEvent`](struct.InvalidEvent.html) contains the error message and the raw data.
|
|
||||||
Err(InvalidEvent),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: TryFromRaw> EventResult<T> {
|
|
||||||
/// Convert `EventResult<T>` into the equivalent `std::result::Result<T, InvalidEvent>`.
|
|
||||||
pub fn into_result(self) -> Result<T, InvalidEvent> {
|
|
||||||
match self {
|
|
||||||
EventResult::Ok(t) => Ok(t),
|
|
||||||
EventResult::Err(invalid_event) => Err(invalid_event),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, T> Deserialize<'de> for EventResult<T>
|
|
||||||
where
|
|
||||||
T: TryFromRaw,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let json = serde_json::Value::deserialize(deserializer)?;
|
|
||||||
|
|
||||||
let raw_data: T::Raw = match serde_json::from_value(json.clone()) {
|
|
||||||
Ok(raw) => raw,
|
|
||||||
Err(error) => {
|
|
||||||
return Ok(EventResult::Err(InvalidEvent {
|
|
||||||
json,
|
|
||||||
message: error.to_string(),
|
|
||||||
kind: InvalidEventKind::Deserialization,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match T::try_from_raw(raw_data) {
|
|
||||||
Ok(value) => Ok(EventResult::Ok(value)),
|
|
||||||
Err(err) => Ok(EventResult::Err(InvalidEvent {
|
|
||||||
message: err.to_string(),
|
|
||||||
json,
|
|
||||||
kind: InvalidEventKind::Validation,
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error when attempting to create a value from a string via the `FromStr` trait.
|
/// An error when attempting to create a value from a string via the `FromStr` trait.
|
||||||
#[derive(Clone, Copy, Eq, Debug, Hash, PartialEq)]
|
#[derive(Clone, Copy, Eq, Debug, Hash, PartialEq)]
|
||||||
pub struct FromStrError;
|
pub struct FromStrError;
|
||||||
|
@ -80,7 +80,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::{PresenceEvent, PresenceEventContent, PresenceState};
|
use super::{PresenceEvent, PresenceEventContent, PresenceState};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization() {
|
fn serialization() {
|
||||||
@ -138,9 +138,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<PresenceEvent>>(json)
|
from_json_value::<EventJson<PresenceEvent>>(json)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
event
|
event
|
||||||
);
|
);
|
||||||
|
@ -440,7 +440,7 @@ mod tests {
|
|||||||
Action, EventMatchCondition, PushCondition, PushRulesEvent, RoomMemberCountCondition,
|
Action, EventMatchCondition, PushCondition, PushRulesEvent, RoomMemberCountCondition,
|
||||||
SenderNotificationPermissionCondition, Tweak,
|
SenderNotificationPermissionCondition, Tweak,
|
||||||
};
|
};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_string_action() {
|
fn serialize_string_action() {
|
||||||
@ -814,9 +814,9 @@ mod tests {
|
|||||||
},
|
},
|
||||||
"type": "m.push_rules"
|
"type": "m.push_rules"
|
||||||
});
|
});
|
||||||
assert!(from_json_value::<EventResult<PushRulesEvent>>(json_data)
|
assert!(from_json_value::<EventJson<PushRulesEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.is_ok());
|
.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,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::{CanonicalAliasEvent, CanonicalAliasEventContent};
|
use super::{CanonicalAliasEvent, CanonicalAliasEventContent};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization_with_optional_fields_as_none() {
|
fn serialization_with_optional_fields_as_none() {
|
||||||
@ -239,9 +239,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<CanonicalAliasEvent>>(json_data)
|
from_json_value::<EventJson<CanonicalAliasEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.alias,
|
.alias,
|
||||||
@ -262,9 +262,9 @@ mod tests {
|
|||||||
"type": "m.room.canonical_alias"
|
"type": "m.room.canonical_alias"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<CanonicalAliasEvent>>(json_data)
|
from_json_value::<EventJson<CanonicalAliasEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.alias,
|
.alias,
|
||||||
@ -285,9 +285,9 @@ mod tests {
|
|||||||
"type": "m.room.canonical_alias"
|
"type": "m.room.canonical_alias"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<CanonicalAliasEvent>>(json_data)
|
from_json_value::<EventJson<CanonicalAliasEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.alias,
|
.alias,
|
||||||
@ -309,9 +309,9 @@ mod tests {
|
|||||||
"type": "m.room.canonical_alias"
|
"type": "m.room.canonical_alias"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<CanonicalAliasEvent>>(json_data)
|
from_json_value::<EventJson<CanonicalAliasEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.alias,
|
.alias,
|
||||||
|
@ -57,7 +57,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::CreateEventContent;
|
use super::CreateEventContent;
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialization() {
|
fn serialization() {
|
||||||
@ -93,9 +93,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<CreateEventContent>>(json)
|
from_json_value::<EventJson<CreateEventContent>>(json)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
content
|
content
|
||||||
);
|
);
|
||||||
|
@ -249,7 +249,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::{Algorithm, EncryptedEventContent, MegolmV1AesSha2Content};
|
use super::{Algorithm, EncryptedEventContent, MegolmV1AesSha2Content};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serializtion() {
|
fn serializtion() {
|
||||||
@ -296,9 +296,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<EncryptedEventContent>>(json_data)
|
from_json_value::<EventJson<EncryptedEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
key_verification_start_content
|
key_verification_start_content
|
||||||
);
|
);
|
||||||
@ -316,9 +316,9 @@ mod tests {
|
|||||||
},
|
},
|
||||||
"algorithm": "m.olm.v1.curve25519-aes-sha2"
|
"algorithm": "m.olm.v1.curve25519-aes-sha2"
|
||||||
});
|
});
|
||||||
let content = from_json_value::<EventResult<EncryptedEventContent>>(json_data)
|
let content = from_json_value::<EventJson<EncryptedEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match content {
|
match content {
|
||||||
@ -335,11 +335,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization_failure() {
|
fn deserialization_failure() {
|
||||||
assert!(from_json_value::<EventResult<EncryptedEventContent>>(
|
assert!(from_json_value::<EventJson<EncryptedEventContent>>(
|
||||||
json!({"algorithm": "m.megolm.v1.aes-sha2"})
|
json!({"algorithm": "m.megolm.v1.aes-sha2"})
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.is_err());
|
.is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1028,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::{AudioMessageEventContent, MessageEventContent};
|
use super::{AudioMessageEventContent, MessageEventContent};
|
||||||
use crate::room::message::{InReplyTo, RelatesTo, TextMessageEventContent};
|
use crate::room::message::{InReplyTo, RelatesTo, TextMessageEventContent};
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
use ruma_identifiers::EventId;
|
use ruma_identifiers::EventId;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
@ -1108,9 +1108,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<MessageEventContent>>(json_data)
|
from_json_value::<EventJson<MessageEventContent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
message_event_content
|
message_event_content
|
||||||
);
|
);
|
||||||
@ -1122,11 +1122,9 @@ mod tests {
|
|||||||
"body": "test","msgtype": "m.location",
|
"body": "test","msgtype": "m.location",
|
||||||
"url": "http://example.com/audio.mp3"
|
"url": "http://example.com/audio.mp3"
|
||||||
});
|
});
|
||||||
assert!(
|
assert!(from_json_value::<EventJson<MessageEventContent>>(json_data)
|
||||||
from_json_value::<EventResult<MessageEventContent>>(json_data)
|
.unwrap()
|
||||||
.unwrap()
|
.deserialize()
|
||||||
.into_result()
|
.is_err());
|
||||||
.is_err()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ mod tests {
|
|||||||
use ruma_identifiers::{EventId, RoomId, UserId};
|
use ruma_identifiers::{EventId, RoomId, UserId};
|
||||||
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 crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
use super::{NameEvent, NameEventContent};
|
use super::{NameEvent, NameEventContent};
|
||||||
|
|
||||||
@ -245,9 +245,9 @@ mod tests {
|
|||||||
"type": "m.room.name"
|
"type": "m.room.name"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<NameEvent>>(json_data)
|
from_json_value::<EventJson<NameEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.name,
|
.name,
|
||||||
@ -264,10 +264,10 @@ mod tests {
|
|||||||
let long_content_json_string: String =
|
let long_content_json_string: String =
|
||||||
serde_json::json!({ "name": &long_string }).to_string();
|
serde_json::json!({ "name": &long_string }).to_string();
|
||||||
|
|
||||||
let from_raw: EventResult<NameEventContent> =
|
let from_raw: EventJson<NameEventContent> =
|
||||||
serde_json::from_str(&long_content_json_string).unwrap();
|
serde_json::from_str(&long_content_json_string).unwrap();
|
||||||
|
|
||||||
let result = from_raw.into_result();
|
let result = from_raw.deserialize();
|
||||||
assert!(result.is_err(), "Result should be invalid: {:?}", result);
|
assert!(result.is_err(), "Result should be invalid: {:?}", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,10 +275,10 @@ mod tests {
|
|||||||
fn json_with_empty_name_creates_content_as_none() {
|
fn json_with_empty_name_creates_content_as_none() {
|
||||||
let long_content_json_string: String = serde_json::json!({ "name": "" }).to_string();
|
let long_content_json_string: String = serde_json::json!({ "name": "" }).to_string();
|
||||||
|
|
||||||
let from_raw: EventResult<NameEventContent> =
|
let from_raw: EventJson<NameEventContent> =
|
||||||
serde_json::from_str(&long_content_json_string).unwrap();
|
serde_json::from_str(&long_content_json_string).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_raw.into_result().unwrap(),
|
from_raw.deserialize().unwrap(),
|
||||||
NameEventContent { name: None }
|
NameEventContent { name: None }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -304,9 +304,9 @@ mod tests {
|
|||||||
"type": "m.room.name"
|
"type": "m.room.name"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<NameEvent>>(json_data)
|
from_json_value::<EventJson<NameEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.name,
|
.name,
|
||||||
@ -327,9 +327,9 @@ mod tests {
|
|||||||
"type": "m.room.name"
|
"type": "m.room.name"
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<NameEvent>>(json_data)
|
from_json_value::<EventJson<NameEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.name,
|
.name,
|
||||||
@ -352,9 +352,9 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
from_json_value::<EventResult<NameEvent>>(json_data)
|
from_json_value::<EventJson<NameEvent>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.content
|
.content
|
||||||
.name,
|
.name,
|
||||||
|
@ -27,7 +27,7 @@ mod tests {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
room::pinned_events::{PinnedEventsEvent, PinnedEventsEventContent},
|
room::pinned_events::{PinnedEventsEvent, PinnedEventsEventContent},
|
||||||
Event, EventResult, RoomEvent, StateEvent,
|
Event, EventJson, RoomEvent, StateEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -50,9 +50,9 @@ mod tests {
|
|||||||
|
|
||||||
let serialized_event = to_string(&event).unwrap();
|
let serialized_event = to_string(&event).unwrap();
|
||||||
let parsed_event: PinnedEventsEvent =
|
let parsed_event: PinnedEventsEvent =
|
||||||
serde_json::from_str::<EventResult<_>>(&serialized_event)
|
serde_json::from_str::<EventJson<_>>(&serialized_event)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(parsed_event.event_id(), event.event_id());
|
assert_eq!(parsed_event.event_id(), event.event_id());
|
||||||
|
@ -174,7 +174,7 @@ mod tests {
|
|||||||
use serde_json::{from_value as from_json_value, json};
|
use serde_json::{from_value as from_json_value, json};
|
||||||
|
|
||||||
use super::ServerAclEvent;
|
use super::ServerAclEvent;
|
||||||
use crate::EventResult;
|
use crate::EventJson;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn default_values() {
|
fn default_values() {
|
||||||
@ -185,9 +185,9 @@ mod tests {
|
|||||||
"state_key": "",
|
"state_key": "",
|
||||||
"type": "m.room.server_acl"
|
"type": "m.room.server_acl"
|
||||||
});
|
});
|
||||||
let server_acl_event: ServerAclEvent = from_json_value::<EventResult<_>>(json_data)
|
let server_acl_event: ServerAclEvent = from_json_value::<EventJson<_>>(json_data)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(server_acl_event.content.allow_ip_literals, true);
|
assert_eq!(server_acl_event.content.allow_ip_literals, true);
|
||||||
|
@ -317,7 +317,7 @@ mod tests {
|
|||||||
use super::{AnyStrippedStateEvent, StrippedRoomName, StrippedRoomTopic};
|
use super::{AnyStrippedStateEvent, StrippedRoomName, StrippedRoomTopic};
|
||||||
use crate::{
|
use crate::{
|
||||||
room::{join_rules::JoinRule, topic::TopicEventContent},
|
room::{join_rules::JoinRule, topic::TopicEventContent},
|
||||||
EventResult, EventType,
|
EventJson, EventType,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -390,9 +390,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match from_json_value::<EventResult<_>>(name_event.clone())
|
match from_json_value::<EventJson<_>>(name_event.clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
AnyStrippedStateEvent::RoomName(event) => {
|
AnyStrippedStateEvent::RoomName(event) => {
|
||||||
@ -405,14 +405,14 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Ensure `StrippedStateContent` can be parsed, not just `StrippedState`.
|
// Ensure `StrippedStateContent` can be parsed, not just `StrippedState`.
|
||||||
assert!(from_json_value::<EventResult<StrippedRoomName>>(name_event)
|
assert!(from_json_value::<EventJson<StrippedRoomName>>(name_event)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.is_ok());
|
.is_ok());
|
||||||
|
|
||||||
match from_json_value::<EventResult<_>>(join_rules_event)
|
match from_json_value::<EventJson<_>>(join_rules_event)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
AnyStrippedStateEvent::RoomJoinRules(event) => {
|
AnyStrippedStateEvent::RoomJoinRules(event) => {
|
||||||
@ -424,9 +424,9 @@ mod tests {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match from_json_value::<EventResult<_>>(avatar_event)
|
match from_json_value::<EventJson<_>>(avatar_event)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
AnyStrippedStateEvent::RoomAvatar(event) => {
|
AnyStrippedStateEvent::RoomAvatar(event) => {
|
||||||
|
@ -272,19 +272,19 @@ mod tests {
|
|||||||
},
|
},
|
||||||
room::encrypted::EncryptedEventContent,
|
room::encrypted::EncryptedEventContent,
|
||||||
room_key_request::Action,
|
room_key_request::Action,
|
||||||
Algorithm, Empty, EventResult,
|
Algorithm, Empty, EventJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! deserialize {
|
macro_rules! deserialize {
|
||||||
($source:ident, $($target:tt)*) => {{
|
($source:ident, $($target:tt)*) => {{
|
||||||
let event = from_json_value::<EventResult<AnyToDeviceEvent>>($source)
|
let event = from_json_value::<EventJson<AnyToDeviceEvent>>($source)
|
||||||
.expect(&format!(
|
.expect(&format!(
|
||||||
"Can't deserialize to-device event: {} from source {}",
|
"Can't deserialize to-device event: {} from source {}",
|
||||||
stringify!($($target)*), stringify!($source)
|
stringify!($($target)*), stringify!($source)
|
||||||
));
|
));
|
||||||
|
|
||||||
let event = event
|
let event = event
|
||||||
.into_result()
|
.deserialize()
|
||||||
.expect("To-device event {} deserialized into a invalid event");
|
.expect("To-device event {} deserialized into a invalid event");
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
|
@ -6,7 +6,7 @@ use serde::{
|
|||||||
};
|
};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{EventResult, TryFromRaw};
|
use crate::{EventJson, TryFromRaw};
|
||||||
|
|
||||||
pub fn try_convert_variant<Enum: TryFromRaw, Content: TryFromRaw>(
|
pub fn try_convert_variant<Enum: TryFromRaw, Content: TryFromRaw>(
|
||||||
variant: fn(Content) -> Enum,
|
variant: fn(Content) -> Enum,
|
||||||
@ -130,9 +130,9 @@ where
|
|||||||
assert_eq!(se, serde_json::to_value(de.clone()).unwrap());
|
assert_eq!(se, serde_json::to_value(de.clone()).unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
de,
|
de,
|
||||||
serde_json::from_value::<EventResult<_>>(se)
|
serde_json::from_value::<EventJson<_>>(se)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_result()
|
.deserialize()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user