use std::fmt;
use ruma_common::serde::{CanBeEmpty, Raw};
use serde::{de::DeserializeOwned, Serialize};
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
use super::{
EphemeralRoomEventType, GlobalAccountDataEventType, MessageLikeEventType,
RoomAccountDataEventType, StateEventType, ToDeviceEventType,
};
pub trait EventContent: Sized + Serialize {
type EventType;
fn event_type(&self) -> Self::EventType;
}
pub trait RawExt<T: EventContentFromType> {
fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T>;
}
impl<T> RawExt<T> for Raw<T>
where
T: EventContentFromType,
T::EventType: fmt::Display,
{
fn deserialize_with_type(&self, event_type: T::EventType) -> serde_json::Result<T> {
T::from_parts(&event_type.to_string(), self.json())
}
}
pub trait StaticEventContent: EventContent {
const TYPE: &'static str;
}
pub trait GlobalAccountDataEventContent:
EventContent<EventType = GlobalAccountDataEventType>
{
}
pub trait RoomAccountDataEventContent: EventContent<EventType = RoomAccountDataEventType> {}
pub trait EphemeralRoomEventContent: EventContent<EventType = EphemeralRoomEventType> {}
pub trait MessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
pub trait RedactedMessageLikeEventContent: EventContent<EventType = MessageLikeEventType> {}
pub trait StateEventContent: EventContent<EventType = StateEventType> {
type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
}
pub trait StaticStateEventContent: StateEventContent {
type PossiblyRedacted: PossiblyRedactedStateEventContent;
type Unsigned: Clone + fmt::Debug + Default + CanBeEmpty + DeserializeOwned;
}
pub trait RedactedStateEventContent: EventContent<EventType = StateEventType> {
type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
}
pub trait PossiblyRedactedStateEventContent: EventContent<EventType = StateEventType> {
type StateKey: AsRef<str> + Clone + fmt::Debug + DeserializeOwned + Serialize;
}
pub trait ToDeviceEventContent: EventContent<EventType = ToDeviceEventType> {}
pub trait EventContentFromType: EventContent {
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self>;
}
impl<T> EventContentFromType for T
where
T: EventContent + DeserializeOwned,
{
fn from_parts(_event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
from_json_str(content.get())
}
}