268 lines
6.4 KiB
Rust
268 lines
6.4 KiB
Rust
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<OwnedServerName>,
|
|
|
|
pub origin_server_ts: UInt,
|
|
|
|
#[serde(rename = "type")]
|
|
pub kind: TimelineEventType,
|
|
|
|
pub content: Box<RawJsonValue>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub state_key: Option<StateKey>,
|
|
|
|
pub prev_events: Vec<OwnedEventId>,
|
|
|
|
pub depth: UInt,
|
|
|
|
pub auth_events: Vec<OwnedEventId>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub redacts: Option<OwnedEventId>,
|
|
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub unsigned: Option<Box<RawJsonValue>>,
|
|
|
|
pub hashes: EventHash,
|
|
|
|
// BTreeMap<Box<ServerName>, BTreeMap<ServerSigningKeyId, String>>
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub signatures: Option<Box<RawJsonValue>>,
|
|
|
|
//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<Self> {
|
|
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<Self> {
|
|
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<Item = &EventId> + Clone + Send + '_ {
|
|
self.auth_events.iter().map(AsRef::as_ref)
|
|
}
|
|
|
|
#[inline]
|
|
fn auth_events_into(
|
|
self,
|
|
) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + 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<Item = &EventId> + 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<Item = &EventId> + Clone + Send + '_ {
|
|
self.auth_events.iter().map(AsRef::as_ref)
|
|
}
|
|
|
|
#[inline]
|
|
fn auth_events_into(
|
|
self,
|
|
) -> impl IntoIterator<IntoIter = impl Iterator<Item = OwnedEventId>> + 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<Item = &EventId> + 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<Ordering> { Some(self.cmp(other)) }
|
|
}
|