renames for core pdu

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-11-07 03:30:47 +00:00
parent e507c31306
commit 79c6b51860
12 changed files with 123 additions and 89 deletions

View file

@ -4,13 +4,13 @@ use serde_json::value::Value as JsonValue;
use crate::{err, implement, Result}; use crate::{err, implement, Result};
#[must_use] #[must_use]
#[implement(super::PduEvent)] #[implement(super::Pdu)]
pub fn get_content_as_value(&self) -> JsonValue { pub fn get_content_as_value(&self) -> JsonValue {
self.get_content() self.get_content()
.expect("pdu content must be a valid JSON value") .expect("pdu content must be a valid JSON value")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
pub fn get_content<T>(&self) -> Result<T> pub fn get_content<T>(&self) -> Result<T>
where where
T: for<'de> Deserialize<'de>, T: for<'de> Deserialize<'de>,

View file

@ -7,12 +7,12 @@ use ruma::api::Direction;
use crate::{err, Error, Result}; use crate::{err, Error, Result};
#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)] #[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
pub enum PduCount { pub enum Count {
Normal(u64), Normal(u64),
Backfilled(i64), Backfilled(i64),
} }
impl PduCount { impl Count {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn from_unsigned(unsigned: u64) -> Self { Self::from_signed(unsigned as i64) } pub fn from_unsigned(unsigned: u64) -> Self { Self::from_signed(unsigned as i64) }
@ -69,11 +69,11 @@ impl PduCount {
Ok(match self { Ok(match self {
Self::Normal(i) => Self::Normal( Self::Normal(i) => Self::Normal(
i.checked_add(add) i.checked_add(add)
.ok_or_else(|| err!(Arithmetic("PduCount::Normal overflow")))?, .ok_or_else(|| err!(Arithmetic("Count::Normal overflow")))?,
), ),
Self::Backfilled(i) => Self::Backfilled( Self::Backfilled(i) => Self::Backfilled(
i.checked_add(add as i64) i.checked_add(add as i64)
.ok_or_else(|| err!(Arithmetic("PduCount::Backfilled overflow")))?, .ok_or_else(|| err!(Arithmetic("Count::Backfilled overflow")))?,
), ),
}) })
} }
@ -83,11 +83,11 @@ impl PduCount {
Ok(match self { Ok(match self {
Self::Normal(i) => Self::Normal( Self::Normal(i) => Self::Normal(
i.checked_sub(sub) i.checked_sub(sub)
.ok_or_else(|| err!(Arithmetic("PduCount::Normal underflow")))?, .ok_or_else(|| err!(Arithmetic("Count::Normal underflow")))?,
), ),
Self::Backfilled(i) => Self::Backfilled( Self::Backfilled(i) => Self::Backfilled(
i.checked_sub(sub as i64) i.checked_sub(sub as i64)
.ok_or_else(|| err!(Arithmetic("PduCount::Backfilled underflow")))?, .ok_or_else(|| err!(Arithmetic("Count::Backfilled underflow")))?,
), ),
}) })
} }
@ -121,11 +121,11 @@ impl PduCount {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn min() -> Self { Self::Backfilled(i64::MIN) } pub const fn min() -> Self { Self::Backfilled(i64::MIN) }
#[inline] #[inline]
#[must_use] #[must_use]
pub fn max() -> Self { Self::Normal(i64::MAX as u64) } pub const fn max() -> Self { Self::Normal(i64::MAX as u64) }
#[inline] #[inline]
pub(crate) fn debug_assert_valid(&self) { pub(crate) fn debug_assert_valid(&self) {
@ -135,7 +135,7 @@ impl PduCount {
} }
} }
impl Display for PduCount { impl Display for Count {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.debug_assert_valid(); self.debug_assert_valid();
match self { match self {
@ -145,20 +145,30 @@ impl Display for PduCount {
} }
} }
impl FromStr for PduCount { impl From<i64> for Count {
#[inline]
fn from(signed: i64) -> Self { Self::from_signed(signed) }
}
impl From<u64> for Count {
#[inline]
fn from(unsigned: u64) -> Self { Self::from_unsigned(unsigned) }
}
impl FromStr for Count {
type Err = Error; type Err = Error;
fn from_str(token: &str) -> Result<Self, Self::Err> { Ok(Self::from_signed(token.parse()?)) } fn from_str(token: &str) -> Result<Self, Self::Err> { Ok(Self::from_signed(token.parse()?)) }
} }
impl PartialOrd for PduCount { impl PartialOrd for Count {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
} }
impl Ord for PduCount { impl Ord for Count {
fn cmp(&self, other: &Self) -> Ordering { self.into_signed().cmp(&other.into_signed()) } fn cmp(&self, other: &Self) -> Ordering { self.into_signed().cmp(&other.into_signed()) }
} }
impl Default for PduCount { impl Default for Count {
fn default() -> Self { Self::Normal(0) } fn default() -> Self { Self::Normal(0) }
} }

View file

@ -4,9 +4,9 @@ pub use ruma::state_res::Event;
use ruma::{events::TimelineEventType, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId}; use ruma::{events::TimelineEventType, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId};
use serde_json::value::RawValue as RawJsonValue; use serde_json::value::RawValue as RawJsonValue;
use super::PduEvent; use super::Pdu;
impl Event for PduEvent { impl Event for Pdu {
type Id = Arc<EventId>; type Id = Arc<EventId>;
fn event_id(&self) -> &Self::Id { &self.event_id } fn event_id(&self) -> &Self::Id { &self.event_id }

View file

@ -3,7 +3,7 @@ use serde_json::Value;
use crate::{implement, is_equal_to}; use crate::{implement, is_equal_to};
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[must_use] #[must_use]
pub fn matches(&self, filter: &RoomEventFilter) -> bool { pub fn matches(&self, filter: &RoomEventFilter) -> bool {
if !self.matches_sender(filter) { if !self.matches_sender(filter) {
@ -25,7 +25,7 @@ pub fn matches(&self, filter: &RoomEventFilter) -> bool {
true true
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
fn matches_room(&self, filter: &RoomEventFilter) -> bool { fn matches_room(&self, filter: &RoomEventFilter) -> bool {
if filter.not_rooms.contains(&self.room_id) { if filter.not_rooms.contains(&self.room_id) {
return false; return false;
@ -40,7 +40,7 @@ fn matches_room(&self, filter: &RoomEventFilter) -> bool {
true true
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
fn matches_sender(&self, filter: &RoomEventFilter) -> bool { fn matches_sender(&self, filter: &RoomEventFilter) -> bool {
if filter.not_senders.contains(&self.sender) { if filter.not_senders.contains(&self.sender) {
return false; return false;
@ -55,7 +55,7 @@ fn matches_sender(&self, filter: &RoomEventFilter) -> bool {
true true
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
fn matches_type(&self, filter: &RoomEventFilter) -> bool { fn matches_type(&self, filter: &RoomEventFilter) -> bool {
let event_type = &self.kind.to_cow_str(); let event_type = &self.kind.to_cow_str();
if filter.not_types.iter().any(is_equal_to!(event_type)) { if filter.not_types.iter().any(is_equal_to!(event_type)) {
@ -71,7 +71,7 @@ fn matches_type(&self, filter: &RoomEventFilter) -> bool {
true true
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
fn matches_url(&self, filter: &RoomEventFilter) -> bool { fn matches_url(&self, filter: &RoomEventFilter) -> bool {
let Some(url_filter) = filter.url_filter.as_ref() else { let Some(url_filter) = filter.url_filter.as_ref() else {
return true; return true;

View file

@ -1,4 +1,4 @@
use super::{PduCount, RawPduId}; use super::{Count, RawId};
use crate::utils::u64_from_u8x8; use crate::utils::u64_from_u8x8;
pub type ShortRoomId = ShortId; pub type ShortRoomId = ShortId;
@ -6,17 +6,17 @@ pub type ShortEventId = ShortId;
pub type ShortId = u64; pub type ShortId = u64;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PduId { pub struct Id {
pub shortroomid: ShortRoomId, pub shortroomid: ShortRoomId,
pub shorteventid: PduCount, pub shorteventid: Count,
} }
impl From<RawPduId> for PduId { impl From<RawId> for Id {
#[inline] #[inline]
fn from(raw: RawPduId) -> Self { fn from(raw: RawId) -> Self {
Self { Self {
shortroomid: u64_from_u8x8(raw.shortroomid()), shortroomid: u64_from_u8x8(raw.shortroomid()),
shorteventid: PduCount::from_unsigned(u64_from_u8x8(raw.shorteventid())), shorteventid: Count::from_unsigned(u64_from_u8x8(raw.shorteventid())),
} }
} }
} }

View file

@ -22,17 +22,18 @@ use serde_json::value::RawValue as RawJsonValue;
pub use self::{ pub use self::{
builder::{Builder, Builder as PduBuilder}, builder::{Builder, Builder as PduBuilder},
count::PduCount, count::Count,
event::Event, event::Event,
event_id::*, event_id::*,
id::*, id::*,
raw_id::*, raw_id::*,
Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId,
}; };
use crate::Result; use crate::Result;
/// Persistent Data Unit (Event) /// Persistent Data Unit (Event)
#[derive(Clone, Deserialize, Serialize, Debug)] #[derive(Clone, Deserialize, Serialize, Debug)]
pub struct PduEvent { pub struct Pdu {
pub event_id: Arc<EventId>, pub event_id: Arc<EventId>,
pub room_id: OwnedRoomId, pub room_id: OwnedRoomId,
pub sender: OwnedUserId, pub sender: OwnedUserId,
@ -64,7 +65,7 @@ pub struct EventHash {
pub sha256: String, pub sha256: String,
} }
impl PduEvent { impl Pdu {
pub fn from_id_val(event_id: &EventId, mut json: CanonicalJsonObject) -> Result<Self> { pub fn from_id_val(event_id: &EventId, mut json: CanonicalJsonObject) -> Result<Self> {
let event_id = CanonicalJsonValue::String(event_id.into()); let event_id = CanonicalJsonValue::String(event_id.into());
json.insert("event_id".into(), event_id); json.insert("event_id".into(), event_id);
@ -75,19 +76,19 @@ impl PduEvent {
} }
/// Prevent derived equality which wouldn't limit itself to event_id /// Prevent derived equality which wouldn't limit itself to event_id
impl Eq for PduEvent {} impl Eq for Pdu {}
/// Equality determined by the Pdu's ID, not the memory representations. /// Equality determined by the Pdu's ID, not the memory representations.
impl PartialEq for PduEvent { impl PartialEq for Pdu {
fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id } fn eq(&self, other: &Self) -> bool { self.event_id == other.event_id }
} }
/// Ordering determined by the Pdu's ID, not the memory representations. /// Ordering determined by the Pdu's ID, not the memory representations.
impl PartialOrd for PduEvent { impl PartialOrd for Pdu {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
} }
/// Ordering determined by the Pdu's ID, not the memory representations. /// Ordering determined by the Pdu's ID, not the memory representations.
impl Ord for PduEvent { impl Ord for Pdu {
fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) } fn cmp(&self, other: &Self) -> Ordering { self.event_id.cmp(&other.event_id) }
} }

View file

@ -1,27 +1,27 @@
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use super::{PduCount, PduId, ShortEventId, ShortId, ShortRoomId}; use super::{Count, Id, ShortEventId, ShortId, ShortRoomId};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum RawPduId { pub enum RawId {
Normal(RawPduIdNormal), Normal(RawIdNormal),
Backfilled(RawPduIdBackfilled), Backfilled(RawIdBackfilled),
} }
type RawPduIdNormal = [u8; RawPduId::NORMAL_LEN]; type RawIdNormal = [u8; RawId::NORMAL_LEN];
type RawPduIdBackfilled = [u8; RawPduId::BACKFILLED_LEN]; type RawIdBackfilled = [u8; RawId::BACKFILLED_LEN];
const INT_LEN: usize = size_of::<ShortId>(); const INT_LEN: usize = size_of::<ShortId>();
impl RawPduId { impl RawId {
const BACKFILLED_LEN: usize = size_of::<ShortRoomId>() + INT_LEN + size_of::<ShortEventId>(); const BACKFILLED_LEN: usize = size_of::<ShortRoomId>() + INT_LEN + size_of::<ShortEventId>();
const MAX_LEN: usize = Self::BACKFILLED_LEN; const MAX_LEN: usize = Self::BACKFILLED_LEN;
const NORMAL_LEN: usize = size_of::<ShortRoomId>() + size_of::<ShortEventId>(); const NORMAL_LEN: usize = size_of::<ShortRoomId>() + size_of::<ShortEventId>();
#[inline] #[inline]
#[must_use] #[must_use]
pub fn pdu_count(&self) -> PduCount { pub fn pdu_count(&self) -> Count {
let id: PduId = (*self).into(); let id: Id = (*self).into();
id.shorteventid id.shorteventid
} }
@ -61,55 +61,51 @@ impl RawPduId {
} }
} }
impl AsRef<[u8]> for RawPduId { impl AsRef<[u8]> for RawId {
#[inline] #[inline]
fn as_ref(&self) -> &[u8] { self.as_bytes() } fn as_ref(&self) -> &[u8] { self.as_bytes() }
} }
impl From<&[u8]> for RawPduId { impl From<&[u8]> for RawId {
#[inline] #[inline]
fn from(id: &[u8]) -> Self { fn from(id: &[u8]) -> Self {
match id.len() { match id.len() {
Self::NORMAL_LEN => Self::Normal( Self::NORMAL_LEN => Self::Normal(
id[0..Self::NORMAL_LEN] id[0..Self::NORMAL_LEN]
.try_into() .try_into()
.expect("normal RawPduId from [u8]"), .expect("normal RawId from [u8]"),
), ),
Self::BACKFILLED_LEN => Self::Backfilled( Self::BACKFILLED_LEN => Self::Backfilled(
id[0..Self::BACKFILLED_LEN] id[0..Self::BACKFILLED_LEN]
.try_into() .try_into()
.expect("backfilled RawPduId from [u8]"), .expect("backfilled RawId from [u8]"),
), ),
_ => unimplemented!("unrecognized RawPduId length"), _ => unimplemented!("unrecognized RawId length"),
} }
} }
} }
impl From<PduId> for RawPduId { impl From<Id> for RawId {
#[inline] #[inline]
fn from(id: PduId) -> Self { fn from(id: Id) -> Self {
const MAX_LEN: usize = RawPduId::MAX_LEN; const MAX_LEN: usize = RawId::MAX_LEN;
type RawVec = ArrayVec<u8, MAX_LEN>; type RawVec = ArrayVec<u8, MAX_LEN>;
let mut vec = RawVec::new(); let mut vec = RawVec::new();
vec.extend(id.shortroomid.to_be_bytes()); vec.extend(id.shortroomid.to_be_bytes());
id.shorteventid.debug_assert_valid(); id.shorteventid.debug_assert_valid();
match id.shorteventid { match id.shorteventid {
PduCount::Normal(shorteventid) => { Count::Normal(shorteventid) => {
vec.extend(shorteventid.to_be_bytes()); vec.extend(shorteventid.to_be_bytes());
Self::Normal( Self::Normal(vec.as_ref().try_into().expect("RawVec into RawId::Normal"))
vec.as_ref()
.try_into()
.expect("RawVec into RawPduId::Normal"),
)
}, },
PduCount::Backfilled(shorteventid) => { Count::Backfilled(shorteventid) => {
vec.extend(0_u64.to_be_bytes()); vec.extend(0_u64.to_be_bytes());
vec.extend(shorteventid.to_be_bytes()); vec.extend(shorteventid.to_be_bytes());
Self::Backfilled( Self::Backfilled(
vec.as_ref() vec.as_ref()
.try_into() .try_into()
.expect("RawVec into RawPduId::Backfilled"), .expect("RawVec into RawId::Backfilled"),
) )
}, },
} }

View file

@ -18,9 +18,9 @@ struct ExtractRedactedBecause {
redacted_because: Option<serde::de::IgnoredAny>, redacted_because: Option<serde::de::IgnoredAny>,
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Result<()> { pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Result {
self.unsigned = None; self.unsigned = None;
let mut content = let mut content =
@ -31,7 +31,7 @@ pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Resul
self.unsigned = Some( self.unsigned = Some(
to_raw_value(&json!({ to_raw_value(&json!({
"redacted_because": serde_json::to_value(reason).expect("to_value(PduEvent) always works") "redacted_because": serde_json::to_value(reason).expect("to_value(Pdu) always works")
})) }))
.expect("to string always works"), .expect("to string always works"),
); );
@ -41,7 +41,7 @@ pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Resul
Ok(()) Ok(())
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[must_use] #[must_use]
pub fn is_redacted(&self) -> bool { pub fn is_redacted(&self) -> bool {
let Some(unsigned) = &self.unsigned else { let Some(unsigned) = &self.unsigned else {
@ -72,7 +72,7 @@ pub fn is_redacted(&self) -> bool {
/// > to the content of m.room.redaction events in older room versions when /// > to the content of m.room.redaction events in older room versions when
/// > serving /// > serving
/// > such events over the Client-Server API. /// > such events over the Client-Server API.
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[must_use] #[must_use]
pub fn copy_redacts(&self) -> (Option<Arc<EventId>>, Box<RawJsonValue>) { pub fn copy_redacts(&self) -> (Option<Arc<EventId>>, Box<RawJsonValue>) {
if self.kind == TimelineEventType::RoomRedaction { if self.kind == TimelineEventType::RoomRedaction {

View file

@ -13,7 +13,7 @@ struct ExtractRelatesToEventId {
relates_to: ExtractRelType, relates_to: ExtractRelType,
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[must_use] #[must_use]
pub fn relation_type_equal(&self, rel_type: &RelationType) -> bool { pub fn relation_type_equal(&self, rel_type: &RelationType) -> bool {
self.get_content() self.get_content()

View file

@ -10,7 +10,7 @@ use serde_json::{json, value::Value as JsonValue};
use crate::{implement, warn}; use crate::{implement, warn};
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> { pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> {
let (redacts, content) = self.copy_redacts(); let (redacts, content) = self.copy_redacts();
@ -36,7 +36,7 @@ pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> {
} }
/// This only works for events that are also AnyRoomEvents. /// This only works for events that are also AnyRoomEvents.
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> { pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> {
let (redacts, content) = self.copy_redacts(); let (redacts, content) = self.copy_redacts();
@ -62,7 +62,7 @@ pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> {
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> { pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> {
let (redacts, content) = self.copy_redacts(); let (redacts, content) = self.copy_redacts();
@ -88,7 +88,7 @@ pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> {
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> { pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> {
let (redacts, content) = self.copy_redacts(); let (redacts, content) = self.copy_redacts();
@ -114,7 +114,7 @@ pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> {
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[must_use] #[must_use]
pub fn to_state_event_value(&self) -> JsonValue { pub fn to_state_event_value(&self) -> JsonValue {
let mut json = json!({ let mut json = json!({
@ -134,13 +134,13 @@ pub fn to_state_event_value(&self) -> JsonValue {
json json
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_state_event(&self) -> Raw<AnyStateEvent> { pub fn to_state_event(&self) -> Raw<AnyStateEvent> {
serde_json::from_value(self.to_state_event_value()).expect("Raw::from_value always works") serde_json::from_value(self.to_state_event_value()).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> { pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> {
let mut json = json!({ let mut json = json!({
@ -159,7 +159,7 @@ pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> {
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_stripped_state_event(&self) -> Raw<AnyStrippedStateEvent> { pub fn to_stripped_state_event(&self) -> Raw<AnyStrippedStateEvent> {
let json = json!({ let json = json!({
@ -172,7 +172,7 @@ pub fn to_stripped_state_event(&self) -> Raw<AnyStrippedStateEvent> {
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_stripped_spacechild_state_event(&self) -> Raw<HierarchySpaceChildEvent> { pub fn to_stripped_spacechild_state_event(&self) -> Raw<HierarchySpaceChildEvent> {
let json = json!({ let json = json!({
@ -186,7 +186,7 @@ pub fn to_stripped_spacechild_state_event(&self) -> Raw<HierarchySpaceChildEvent
serde_json::from_value(json).expect("Raw::from_value always works") serde_json::from_value(json).expect("Raw::from_value always works")
} }
#[implement(super::PduEvent)] #[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")] #[tracing::instrument(skip(self), level = "debug")]
pub fn to_member_event(&self) -> Raw<StateEvent<RoomMemberEventContent>> { pub fn to_member_event(&self) -> Raw<StateEvent<RoomMemberEventContent>> {
let mut json = json!({ let mut json = json!({

View file

@ -1,19 +1,19 @@
#![cfg(test)] #![cfg(test)]
use super::PduCount; use super::Count;
#[test] #[test]
fn backfilled_parse() { fn backfilled_parse() {
let count: PduCount = "-987654".parse().expect("parse() failed"); let count: Count = "-987654".parse().expect("parse() failed");
let backfilled = matches!(count, PduCount::Backfilled(_)); let backfilled = matches!(count, Count::Backfilled(_));
assert!(backfilled, "not backfilled variant"); assert!(backfilled, "not backfilled variant");
} }
#[test] #[test]
fn normal_parse() { fn normal_parse() {
let count: PduCount = "987654".parse().expect("parse() failed"); let count: Count = "987654".parse().expect("parse() failed");
let backfilled = matches!(count, PduCount::Backfilled(_)); let backfilled = matches!(count, Count::Backfilled(_));
assert!(!backfilled, "backfilled variant"); assert!(!backfilled, "backfilled variant");
} }

View file

@ -4,10 +4,11 @@ use ruma::MilliSecondsSinceUnixEpoch;
use serde::Deserialize; use serde::Deserialize;
use serde_json::value::{to_raw_value, RawValue as RawJsonValue, Value as JsonValue}; use serde_json::value::{to_raw_value, RawValue as RawJsonValue, Value as JsonValue};
use super::Pdu;
use crate::{err, implement, is_true, Result}; use crate::{err, implement, is_true, Result};
#[implement(super::PduEvent)] #[implement(Pdu)]
pub fn remove_transaction_id(&mut self) -> Result<()> { pub fn remove_transaction_id(&mut self) -> Result {
let Some(unsigned) = &self.unsigned else { let Some(unsigned) = &self.unsigned else {
return Ok(()); return Ok(());
}; };
@ -23,8 +24,8 @@ pub fn remove_transaction_id(&mut self) -> Result<()> {
Ok(()) Ok(())
} }
#[implement(super::PduEvent)] #[implement(Pdu)]
pub fn add_age(&mut self) -> Result<()> { pub fn add_age(&mut self) -> Result {
let mut unsigned: BTreeMap<String, Box<RawJsonValue>> = self let mut unsigned: BTreeMap<String, Box<RawJsonValue>> = self
.unsigned .unsigned
.as_ref() .as_ref()
@ -44,7 +45,33 @@ pub fn add_age(&mut self) -> Result<()> {
Ok(()) Ok(())
} }
#[implement(super::PduEvent)] #[implement(Pdu)]
pub fn add_relation(&mut self, name: &str, pdu: &Pdu) -> Result {
let mut unsigned: BTreeMap<String, JsonValue> = self
.unsigned
.as_ref()
.map_or_else(|| Ok(BTreeMap::new()), |u| serde_json::from_str(u.get()))
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
let relations: &mut JsonValue = unsigned.entry("m.relations".into()).or_default();
if relations.as_object_mut().is_none() {
let mut object = serde_json::Map::<String, JsonValue>::new();
_ = relations.as_object_mut().insert(&mut object);
}
relations
.as_object_mut()
.expect("we just created it")
.insert(name.to_owned(), serde_json::to_value(pdu)?);
self.unsigned = to_raw_value(&unsigned)
.map(Some)
.expect("unsigned is valid");
Ok(())
}
#[implement(Pdu)]
pub fn contains_unsigned_property<F>(&self, property: &str, is_type: F) -> bool pub fn contains_unsigned_property<F>(&self, property: &str, is_type: F) -> bool
where where
F: FnOnce(&JsonValue) -> bool, F: FnOnce(&JsonValue) -> bool,
@ -55,7 +82,7 @@ where
.is_some_and(is_true!()) .is_some_and(is_true!())
} }
#[implement(super::PduEvent)] #[implement(Pdu)]
pub fn get_unsigned_property<T>(&self, property: &str) -> Result<T> pub fn get_unsigned_property<T>(&self, property: &str) -> Result<T>
where where
T: for<'de> Deserialize<'de>, T: for<'de> Deserialize<'de>,
@ -68,11 +95,11 @@ where
.map_err(|e| err!(Database("Failed to deserialize unsigned.{property} into type: {e}"))) .map_err(|e| err!(Database("Failed to deserialize unsigned.{property} into type: {e}")))
} }
#[implement(super::PduEvent)] #[implement(Pdu)]
#[must_use] #[must_use]
pub fn get_unsigned_as_value(&self) -> JsonValue { self.get_unsigned::<JsonValue>().unwrap_or_default() } pub fn get_unsigned_as_value(&self) -> JsonValue { self.get_unsigned::<JsonValue>().unwrap_or_default() }
#[implement(super::PduEvent)] #[implement(Pdu)]
pub fn get_unsigned<T>(&self) -> Result<JsonValue> { pub fn get_unsigned<T>(&self) -> Result<JsonValue> {
self.unsigned self.unsigned
.as_ref() .as_ref()