Add examples to the docs of Raw and the ruma-events module

This commit is contained in:
Devin Ragotzy 2020-12-07 08:57:23 -08:00 committed by GitHub
parent ee814aa849
commit 724a48d616
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 1 deletions

View File

@ -69,6 +69,72 @@
//! respective event traits whose `content` field is simply a `serde_json::Value` value, which //! respective event traits whose `content` field is simply a `serde_json::Value` value, which
//! represents arbitrary JSON. //! represents arbitrary JSON.
//! //!
//! ## Extending Ruma with custom events
//!
//! For our example we will create a reaction message event. This can be used with ruma-events
//! structs, for this event we will use a `SyncMessageEvent` struct but any `MessageEvent` struct
//! would work.
//!
//! ```rust
//! use ruma_events::{macros::MessageEventContent, SyncMessageEvent};
//! use ruma_identifiers::EventId;
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Clone, Debug, Deserialize, Serialize)]
//! #[serde(tag = "rel_type")]
//! pub enum RelatesTo {
//! #[serde(rename = "m.annotation")]
//! Annotation {
//! /// The event this reaction relates to.
//! event_id: EventId,
//! /// The displayable content of the reaction.
//! key: String,
//! },
//!
//! /// Since this event is not fully specified in the Matrix spec
//! /// it may change or types may be added, we are ready!
//! #[serde(rename = "m.whatever")]
//! Whatever,
//! }
//!
//! /// The payload for our reaction event.
//! #[derive(Clone, Debug, Deserialize, Serialize, MessageEventContent)]
//! #[ruma_event(type = "m.reaction")]
//! pub struct ReactionEventContent {
//! #[serde(rename = "m.relates_to")]
//! pub relates_to: RelatesTo,
//! }
//!
//! let json = serde_json::json!({
//! "content": {
//! "m.relates_to": {
//! "event_id": "$xxxx-xxxx",
//! "key": "👍",
//! "rel_type": "m.annotation"
//! }
//! },
//! "event_id": "$xxxx-xxxx",
//! "origin_server_ts": 1,
//! "sender": "@someone:example.org",
//! "type": "m.reaction",
//! "unsigned": {
//! "age": 85
//! }
//! });
//!
//! // The downside of this event is we cannot use it with the `AnyRoomEvent` or `AnyEvent` enums,
//! // but could be deserialized from a `Raw<AnyRoomEvent>` that has failed.
//! matches::assert_matches!(
//! serde_json::from_value::<SyncMessageEvent<ReactionEventContent>>(json),
//! Ok(SyncMessageEvent {
//! content: ReactionEventContent {
//! relates_to: RelatesTo::Annotation { key, .. },
//! },
//! ..
//! }) if key == "👍"
//! );
//! ```
//!
//! # 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
@ -82,7 +148,7 @@
//! 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
//! `Raw<ContentType>` for dedicated content types) or `Deserialize` (when the content is a //! `Raw<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 independently of the surrounding
//! event structure, if needed. //! event structure, if needed.
//! //!
//! # Collections //! # Collections

View File

@ -13,6 +13,21 @@ use serde_json::value::RawValue;
/// A wrapper around `Box<RawValue>`, to be used in place of any type in the Matrix endpoint /// A wrapper around `Box<RawValue>`, to be used in place of any type in the Matrix endpoint
/// definition to allow request and response types to contain that said type represented by /// definition to allow request and response types to contain that said type represented by
/// the generic argument `Ev`. /// the generic argument `Ev`.
///
/// Ruma offers the `Raw` wrapper to enable passing around JSON text that is only partially
/// validated. This is useful when a client receives events that do not follow the spec perfectly
/// or a server needs to generate reference hashes with the original canonical JSON string.
/// All event structs and enums implement `Serialize` / `Deserialize`, `Raw` should be used
/// to pass around events in a lossless way.
///
/// ```ignore
/// let json = r#"{ "type": "imagine a full event", "content": {...} }"#;
///
/// let deser = serde_json::from_str::<Raw<AnyRoomEvent>>(json)
/// .unwrap() // the first Result from serde_json::from_str, will not fail
/// .deserialize() // deserialize to the inner type
/// .unwrap(); // finally get to the AnyRoomEvent
/// ```
pub struct Raw<T> { pub struct Raw<T> {
json: Box<RawValue>, json: Box<RawValue>,
_ev: PhantomData<T>, _ev: PhantomData<T>,