mod builder; mod count; pub mod format; mod hashes; mod id; mod raw_id; mod redact; #[cfg(test)] mod tests; mod unsigned; use std::cmp::Ordering; use ruma::{ CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, UInt, UserId, events::TimelineEventType, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; pub use self::{ Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId, builder::{Builder, Builder as PduBuilder}, count::Count, hashes::EventHashes as EventHash, id::{ShortId, *}, raw_id::*, }; use super::{Event, StateKey}; use crate::Result; /// Persistent Data Unit (Event) #[derive(Clone, Deserialize, Serialize, Debug)] pub struct Pdu { pub event_id: OwnedEventId, pub room_id: OwnedRoomId, pub sender: OwnedUserId, #[serde(skip_serializing_if = "Option::is_none")] pub origin: Option, pub origin_server_ts: UInt, #[serde(rename = "type")] pub kind: TimelineEventType, pub content: Box, #[serde(skip_serializing_if = "Option::is_none")] pub state_key: Option, pub prev_events: Vec, pub depth: UInt, pub auth_events: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub redacts: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub unsigned: Option>, pub hashes: EventHash, // BTreeMap, BTreeMap> #[serde(default, skip_serializing_if = "Option::is_none")] pub signatures: Option>, //TODO: https://spec.matrix.org/v1.14/rooms/v11/#rejected-events #[cfg(test)] #[serde(default, skip_serializing)] pub rejected: bool, } /// The [maximum size allowed] for a PDU. /// [maximum size allowed]: https://spec.matrix.org/latest/client-server-api/#size-limits pub const MAX_PDU_BYTES: usize = 65_535; /// The [maximum length allowed] for the `prev_events` array of a PDU. /// [maximum length allowed]: https://spec.matrix.org/latest/rooms/v1/#event-format pub const MAX_PREV_EVENTS: usize = 20; /// The [maximum length allowed] for the `auth_events` array of a PDU. /// [maximum length allowed]: https://spec.matrix.org/latest/rooms/v1/#event-format pub const MAX_AUTH_EVENTS: usize = 10; impl Pdu { pub fn from_rid_val( room_id: &RoomId, event_id: &EventId, mut json: CanonicalJsonObject, ) -> Result { let room_id = CanonicalJsonValue::String(room_id.into()); json.insert("room_id".into(), room_id); Self::from_id_val(event_id, json) } pub fn from_id_val(event_id: &EventId, mut json: CanonicalJsonObject) -> Result { let event_id = CanonicalJsonValue::String(event_id.into()); json.insert("event_id".into(), event_id); serde_json::to_value(json) .and_then(serde_json::from_value) .map_err(Into::into) } } impl Event for Pdu where Self: Send + Sync + 'static, { #[inline] fn auth_events(&self) -> impl DoubleEndedIterator + Clone + Send + '_ { self.auth_events.iter().map(AsRef::as_ref) } #[inline] fn auth_events_into( self, ) -> impl IntoIterator> + Send { self.auth_events.into_iter() } #[inline] fn content(&self) -> &RawJsonValue { &self.content } #[inline] fn event_id(&self) -> &EventId { &self.event_id } #[inline] fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch { MilliSecondsSinceUnixEpoch(self.origin_server_ts) } #[inline] fn prev_events(&self) -> impl DoubleEndedIterator + Clone + Send + '_ { self.prev_events.iter().map(AsRef::as_ref) } #[inline] fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() } #[cfg(test)] #[inline] fn rejected(&self) -> bool { self.rejected } #[cfg(not(test))] #[inline] fn rejected(&self) -> bool { false } #[inline] fn room_id(&self) -> &RoomId { &self.room_id } #[inline] fn sender(&self) -> &UserId { &self.sender } #[inline] fn state_key(&self) -> Option<&str> { self.state_key.as_deref() } #[inline] fn kind(&self) -> &TimelineEventType { &self.kind } #[inline] fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_deref() } #[inline] fn as_mut_pdu(&mut self) -> &mut Pdu { self } #[inline] fn as_pdu(&self) -> &Pdu { self } #[inline] fn into_pdu(self) -> Pdu { self } #[inline] fn is_owned(&self) -> bool { true } } impl Event for &Pdu where Self: Send, { #[inline] fn auth_events(&self) -> impl DoubleEndedIterator + Clone + Send + '_ { self.auth_events.iter().map(AsRef::as_ref) } #[inline] fn auth_events_into( self, ) -> impl IntoIterator> + Send { self.auth_events.iter().map(ToOwned::to_owned) } #[inline] fn content(&self) -> &RawJsonValue { &self.content } #[inline] fn event_id(&self) -> &EventId { &self.event_id } #[inline] fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch { MilliSecondsSinceUnixEpoch(self.origin_server_ts) } #[inline] fn prev_events(&self) -> impl DoubleEndedIterator + Clone + Send + '_ { self.prev_events.iter().map(AsRef::as_ref) } #[inline] fn redacts(&self) -> Option<&EventId> { self.redacts.as_deref() } #[cfg(test)] #[inline] fn rejected(&self) -> bool { self.rejected } #[cfg(not(test))] #[inline] fn rejected(&self) -> bool { false } #[inline] fn room_id(&self) -> &RoomId { &self.room_id } #[inline] fn sender(&self) -> &UserId { &self.sender } #[inline] fn state_key(&self) -> Option<&str> { self.state_key.as_deref() } #[inline] fn kind(&self) -> &TimelineEventType { &self.kind } #[inline] fn unsigned(&self) -> Option<&RawJsonValue> { self.unsigned.as_deref() } #[inline] fn as_pdu(&self) -> &Pdu { self } #[inline] fn into_pdu(self) -> Pdu { self.clone() } #[inline] fn is_owned(&self) -> bool { false } } /// Prevent derived equality which wouldn't limit itself to event_id impl Eq for Pdu {} /// Equality determined by the Pdu's ID, not the memory representations. impl PartialEq for Pdu { fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id } } /// Ordering determined by the Pdu's ID, not the memory representations. impl Ord for Pdu { fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) } } /// Ordering determined by the Pdu's ID, not the memory representations. impl PartialOrd for Pdu { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } }