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};
#[must_use]
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
pub fn get_content_as_value(&self) -> JsonValue {
self.get_content()
.expect("pdu content must be a valid JSON value")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
pub fn get_content<T>(&self) -> Result<T>
where
T: for<'de> Deserialize<'de>,

View file

@ -7,12 +7,12 @@ use ruma::api::Direction;
use crate::{err, Error, Result};
#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
pub enum PduCount {
pub enum Count {
Normal(u64),
Backfilled(i64),
}
impl PduCount {
impl Count {
#[inline]
#[must_use]
pub fn from_unsigned(unsigned: u64) -> Self { Self::from_signed(unsigned as i64) }
@ -69,11 +69,11 @@ impl PduCount {
Ok(match self {
Self::Normal(i) => Self::Normal(
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(
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 {
Self::Normal(i) => Self::Normal(
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(
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]
#[must_use]
pub fn min() -> Self { Self::Backfilled(i64::MIN) }
pub const fn min() -> Self { Self::Backfilled(i64::MIN) }
#[inline]
#[must_use]
pub fn max() -> Self { Self::Normal(i64::MAX as u64) }
pub const fn max() -> Self { Self::Normal(i64::MAX as u64) }
#[inline]
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> {
self.debug_assert_valid();
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;
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)) }
}
impl Ord for PduCount {
impl Ord for Count {
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) }
}

View file

@ -4,9 +4,9 @@ pub use ruma::state_res::Event;
use ruma::{events::TimelineEventType, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId};
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>;
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};
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[must_use]
pub fn matches(&self, filter: &RoomEventFilter) -> bool {
if !self.matches_sender(filter) {
@ -25,7 +25,7 @@ pub fn matches(&self, filter: &RoomEventFilter) -> bool {
true
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
fn matches_room(&self, filter: &RoomEventFilter) -> bool {
if filter.not_rooms.contains(&self.room_id) {
return false;
@ -40,7 +40,7 @@ fn matches_room(&self, filter: &RoomEventFilter) -> bool {
true
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
fn matches_sender(&self, filter: &RoomEventFilter) -> bool {
if filter.not_senders.contains(&self.sender) {
return false;
@ -55,7 +55,7 @@ fn matches_sender(&self, filter: &RoomEventFilter) -> bool {
true
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
fn matches_type(&self, filter: &RoomEventFilter) -> bool {
let event_type = &self.kind.to_cow_str();
if filter.not_types.iter().any(is_equal_to!(event_type)) {
@ -71,7 +71,7 @@ fn matches_type(&self, filter: &RoomEventFilter) -> bool {
true
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
fn matches_url(&self, filter: &RoomEventFilter) -> bool {
let Some(url_filter) = filter.url_filter.as_ref() else {
return true;

View file

@ -1,4 +1,4 @@
use super::{PduCount, RawPduId};
use super::{Count, RawId};
use crate::utils::u64_from_u8x8;
pub type ShortRoomId = ShortId;
@ -6,17 +6,17 @@ pub type ShortEventId = ShortId;
pub type ShortId = u64;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PduId {
pub struct Id {
pub shortroomid: ShortRoomId,
pub shorteventid: PduCount,
pub shorteventid: Count,
}
impl From<RawPduId> for PduId {
impl From<RawId> for Id {
#[inline]
fn from(raw: RawPduId) -> Self {
fn from(raw: RawId) -> Self {
Self {
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::{
builder::{Builder, Builder as PduBuilder},
count::PduCount,
count::Count,
event::Event,
event_id::*,
id::*,
raw_id::*,
Count as PduCount, Id as PduId, Pdu as PduEvent, RawId as RawPduId,
};
use crate::Result;
/// Persistent Data Unit (Event)
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct PduEvent {
pub struct Pdu {
pub event_id: Arc<EventId>,
pub room_id: OwnedRoomId,
pub sender: OwnedUserId,
@ -64,7 +65,7 @@ pub struct EventHash {
pub sha256: String,
}
impl PduEvent {
impl Pdu {
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);
@ -75,19 +76,19 @@ impl PduEvent {
}
/// 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.
impl PartialEq for PduEvent {
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 PartialOrd for PduEvent {
impl PartialOrd for Pdu {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}
/// 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) }
}

View file

@ -1,27 +1,27 @@
use arrayvec::ArrayVec;
use super::{PduCount, PduId, ShortEventId, ShortId, ShortRoomId};
use super::{Count, Id, ShortEventId, ShortId, ShortRoomId};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum RawPduId {
Normal(RawPduIdNormal),
Backfilled(RawPduIdBackfilled),
pub enum RawId {
Normal(RawIdNormal),
Backfilled(RawIdBackfilled),
}
type RawPduIdNormal = [u8; RawPduId::NORMAL_LEN];
type RawPduIdBackfilled = [u8; RawPduId::BACKFILLED_LEN];
type RawIdNormal = [u8; RawId::NORMAL_LEN];
type RawIdBackfilled = [u8; RawId::BACKFILLED_LEN];
const INT_LEN: usize = size_of::<ShortId>();
impl RawPduId {
impl RawId {
const BACKFILLED_LEN: usize = size_of::<ShortRoomId>() + INT_LEN + size_of::<ShortEventId>();
const MAX_LEN: usize = Self::BACKFILLED_LEN;
const NORMAL_LEN: usize = size_of::<ShortRoomId>() + size_of::<ShortEventId>();
#[inline]
#[must_use]
pub fn pdu_count(&self) -> PduCount {
let id: PduId = (*self).into();
pub fn pdu_count(&self) -> Count {
let id: Id = (*self).into();
id.shorteventid
}
@ -61,55 +61,51 @@ impl RawPduId {
}
}
impl AsRef<[u8]> for RawPduId {
impl AsRef<[u8]> for RawId {
#[inline]
fn as_ref(&self) -> &[u8] { self.as_bytes() }
}
impl From<&[u8]> for RawPduId {
impl From<&[u8]> for RawId {
#[inline]
fn from(id: &[u8]) -> Self {
match id.len() {
Self::NORMAL_LEN => Self::Normal(
id[0..Self::NORMAL_LEN]
.try_into()
.expect("normal RawPduId from [u8]"),
.expect("normal RawId from [u8]"),
),
Self::BACKFILLED_LEN => Self::Backfilled(
id[0..Self::BACKFILLED_LEN]
.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]
fn from(id: PduId) -> Self {
const MAX_LEN: usize = RawPduId::MAX_LEN;
fn from(id: Id) -> Self {
const MAX_LEN: usize = RawId::MAX_LEN;
type RawVec = ArrayVec<u8, MAX_LEN>;
let mut vec = RawVec::new();
vec.extend(id.shortroomid.to_be_bytes());
id.shorteventid.debug_assert_valid();
match id.shorteventid {
PduCount::Normal(shorteventid) => {
Count::Normal(shorteventid) => {
vec.extend(shorteventid.to_be_bytes());
Self::Normal(
vec.as_ref()
.try_into()
.expect("RawVec into RawPduId::Normal"),
)
Self::Normal(vec.as_ref().try_into().expect("RawVec into RawId::Normal"))
},
PduCount::Backfilled(shorteventid) => {
Count::Backfilled(shorteventid) => {
vec.extend(0_u64.to_be_bytes());
vec.extend(shorteventid.to_be_bytes());
Self::Backfilled(
vec.as_ref()
.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>,
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[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;
let mut content =
@ -31,7 +31,7 @@ pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Resul
self.unsigned = Some(
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"),
);
@ -41,7 +41,7 @@ pub fn redact(&mut self, room_version_id: RoomVersionId, reason: &Self) -> Resul
Ok(())
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[must_use]
pub fn is_redacted(&self) -> bool {
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
/// > serving
/// > such events over the Client-Server API.
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[must_use]
pub fn copy_redacts(&self) -> (Option<Arc<EventId>>, Box<RawJsonValue>) {
if self.kind == TimelineEventType::RoomRedaction {

View file

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

View file

@ -10,7 +10,7 @@ use serde_json::{json, value::Value as JsonValue};
use crate::{implement, warn};
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_sync_room_event(&self) -> Raw<AnySyncTimelineEvent> {
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.
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_any_event(&self) -> Raw<AnyEphemeralRoomEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_room_event(&self) -> Raw<AnyTimelineEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_message_like_event(&self) -> Raw<AnyMessageLikeEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[must_use]
pub fn to_state_event_value(&self) -> JsonValue {
let mut json = json!({
@ -134,13 +134,13 @@ pub fn to_state_event_value(&self) -> JsonValue {
json
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_state_event(&self) -> Raw<AnyStateEvent> {
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")]
pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_stripped_state_event(&self) -> Raw<AnyStrippedStateEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_stripped_spacechild_state_event(&self) -> Raw<HierarchySpaceChildEvent> {
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")
}
#[implement(super::PduEvent)]
#[implement(super::Pdu)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn to_member_event(&self) -> Raw<StateEvent<RoomMemberEventContent>> {
let mut json = json!({

View file

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

View file

@ -4,10 +4,11 @@ use ruma::MilliSecondsSinceUnixEpoch;
use serde::Deserialize;
use serde_json::value::{to_raw_value, RawValue as RawJsonValue, Value as JsonValue};
use super::Pdu;
use crate::{err, implement, is_true, Result};
#[implement(super::PduEvent)]
pub fn remove_transaction_id(&mut self) -> Result<()> {
#[implement(Pdu)]
pub fn remove_transaction_id(&mut self) -> Result {
let Some(unsigned) = &self.unsigned else {
return Ok(());
};
@ -23,8 +24,8 @@ pub fn remove_transaction_id(&mut self) -> Result<()> {
Ok(())
}
#[implement(super::PduEvent)]
pub fn add_age(&mut self) -> Result<()> {
#[implement(Pdu)]
pub fn add_age(&mut self) -> Result {
let mut unsigned: BTreeMap<String, Box<RawJsonValue>> = self
.unsigned
.as_ref()
@ -44,7 +45,33 @@ pub fn add_age(&mut self) -> Result<()> {
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
where
F: FnOnce(&JsonValue) -> bool,
@ -55,7 +82,7 @@ where
.is_some_and(is_true!())
}
#[implement(super::PduEvent)]
#[implement(Pdu)]
pub fn get_unsigned_property<T>(&self, property: &str) -> Result<T>
where
T: for<'de> Deserialize<'de>,
@ -68,11 +95,11 @@ where
.map_err(|e| err!(Database("Failed to deserialize unsigned.{property} into type: {e}")))
}
#[implement(super::PduEvent)]
#[implement(Pdu)]
#[must_use]
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> {
self.unsigned
.as_ref()