identifiers: Make EventId a DST

This commit is contained in:
Jonas Platte 2021-09-17 23:42:46 +02:00
parent c73eb7dce3
commit 52608cc72c
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
55 changed files with 406 additions and 407 deletions

View File

@ -40,7 +40,7 @@ ruma_api! {
response: {
/// A unique identifier for the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
error: crate::Error
@ -80,7 +80,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given event id.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}

View File

@ -36,7 +36,7 @@ ruma_api! {
response: {
/// The ID of the redacted event.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
error: crate::Error
@ -51,7 +51,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given event ID.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}

View File

@ -415,7 +415,7 @@ pub struct ResultGroup {
/// Which results are in this group.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub results: Vec<EventId>,
pub results: Vec<Box<EventId>>,
}
impl ResultGroup {

View File

@ -18,7 +18,7 @@ ruma_api! {
response: {
/// A unique identifier for the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
error: crate::Error
@ -77,7 +77,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given event id.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}

View File

@ -52,7 +52,7 @@ pub struct MessageEvent<C: MessageEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -77,7 +77,7 @@ pub struct SyncMessageEvent<C: MessageEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -99,7 +99,7 @@ pub struct RedactedMessageEvent<C: RedactedMessageEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -124,7 +124,7 @@ pub struct RedactedSyncMessageEvent<C: RedactedMessageEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -146,7 +146,7 @@ pub struct StateEvent<C: StateEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -180,7 +180,7 @@ pub struct SyncStateEvent<C: StateEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -243,7 +243,7 @@ pub struct RedactedStateEvent<C: RedactedStateEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -274,7 +274,7 @@ pub struct RedactedSyncStateEvent<C: RedactedStateEventContent> {
pub content: C,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,

View File

@ -14,12 +14,12 @@ use serde::{Deserialize, Serialize};
#[ruma_event(type = "m.fully_read", kind = RoomAccountData)]
pub struct FullyReadEventContent {
/// The event the user's read marker is located at in the room.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
impl FullyReadEventContent {
/// Creates a new `FullyReadEventContent` with the given event ID.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}

View File

@ -125,13 +125,13 @@ impl ShortAuthenticationString {
#[serde(tag = "rel_type", rename = "m.reference")]
pub struct Relation {
/// The event ID of a related `m.key.verification.request`.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
#[cfg(feature = "unstable-pre-spec")]
impl Relation {
/// Creates a new `Relation` with the given event ID.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}

View File

@ -250,7 +250,7 @@ mod tests {
let event_id = event_id!("$1598361704261elfgc:localhost");
let key_verification_accept_content = KeyVerificationAcceptEventContent {
relates_to: Relation { event_id: event_id.clone() },
relates_to: Relation { event_id: event_id.to_owned() },
method: AcceptMethod::SasV1(SasV1Content {
hash: HashAlgorithm::Sha256,
key_agreement_protocol: KeyAgreementProtocol::Curve25519,
@ -411,7 +411,7 @@ mod tests {
short_authentication_string,
})
} if commitment == "test_commitment"
&& event_id == id
&& *event_id == *id
&& hash == HashAlgorithm::Sha256
&& key_agreement_protocol == KeyAgreementProtocol::Curve25519
&& message_authentication_code == MessageAuthenticationCode::HkdfHmacSha256

View File

@ -55,7 +55,7 @@ mod tests {
#[test]
fn serialization() {
let event_id = event_id!("$1598361704261elfgc:localhost");
let event_id = event_id!("$1598361704261elfgc:localhost").to_owned();
let json_data = json!({
"m.relates_to": {
@ -86,7 +86,7 @@ mod tests {
relates_to: Relation {
event_id
},
} if event_id == id
} if *event_id == *id
);
}
}

View File

@ -81,7 +81,7 @@ mod tests {
#[test]
fn serialization() {
let event_id = event_id!("$1598361704261elfgc:localhost");
let event_id = event_id!("$1598361704261elfgc:localhost").to_owned();
let device: Box<DeviceId> = "123".into();
let json_data = json!({

View File

@ -312,7 +312,7 @@ mod tests {
let key_verification_start_content = KeyVerificationStartEventContent {
from_device: "123".into(),
relates_to: Relation { event_id: event_id.clone() },
relates_to: Relation { event_id: event_id.to_owned() },
method: StartMethod::SasV1(
SasV1ContentInit {
hashes: vec![HashAlgorithm::Sha256],
@ -343,7 +343,7 @@ mod tests {
let key_verification_start_content = KeyVerificationStartEventContent {
from_device: "123".into(),
relates_to: Relation { event_id: event_id.clone() },
relates_to: Relation { event_id: event_id.to_owned() },
method: StartMethod::ReciprocateV1(ReciprocateV1Content::new(secret.clone())),
};

View File

@ -46,7 +46,7 @@
//! #[serde(rename = "m.annotation")]
//! Annotation {
//! /// The event this reaction relates to.
//! event_id: EventId,
//! event_id: Box<EventId>,
//! /// The displayable content of the reaction.
//! key: String,
//! },

View File

@ -1,9 +1,9 @@
//! Types for persistent data unit schemas
//!
//! The differences between the `RoomV1Pdu` schema and the `RoomV3Pdu` schema are
//! that the `RoomV1Pdu` takes an `event_id` field (`RoomV3Pdu` does not), and
//! `auth_events` and `prev_events` take `Vec<(EventId, EventHash)> rather than
//! `Vec<EventId>` in `RoomV3Pdu`.
//! The differences between the `RoomV1Pdu` schema and the `RoomV3Pdu` schema are that the
//! `RoomV1Pdu` takes an `event_id` field (`RoomV3Pdu` does not), and `auth_events` and
//! `prev_events` take `Vec<(Box<EventId>, EventHash)> rather than `Vec<Box<EventId>>` in
//! `RoomV3Pdu`.
use std::collections::BTreeMap;
@ -35,7 +35,7 @@ pub enum Pdu {
#[allow(clippy::exhaustive_structs)]
pub struct RoomV1Pdu {
/// Event ID for the PDU.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The room this event belongs to.
pub room_id: RoomId,
@ -66,7 +66,7 @@ pub struct RoomV1Pdu {
/// Event IDs for the most recent events in the room that the homeserver was
/// aware of when it created this event.
#[serde(skip_serializing_if = "Vec::is_empty")]
pub prev_events: Vec<(EventId, EventHash)>,
pub prev_events: Vec<(Box<EventId>, EventHash)>,
/// The maximum depth of the `prev_events`, plus one.
pub depth: UInt,
@ -74,11 +74,11 @@ pub struct RoomV1Pdu {
/// Event IDs for the authorization events that would allow this event to be
/// in the room.
#[serde(skip_serializing_if = "Vec::is_empty")]
pub auth_events: Vec<(EventId, EventHash)>,
pub auth_events: Vec<(Box<EventId>, EventHash)>,
/// For redaction events, the ID of the event being redacted.
#[serde(skip_serializing_if = "Option::is_none")]
pub redacts: Option<EventId>,
pub redacts: Option<Box<EventId>>,
/// Additional data added by the origin server but not covered by the
/// signatures.
@ -124,18 +124,18 @@ pub struct RoomV3Pdu {
/// Event IDs for the most recent events in the room that the homeserver was
/// aware of when it created this event.
pub prev_events: Vec<EventId>,
pub prev_events: Vec<Box<EventId>>,
/// The maximum depth of the `prev_events`, plus one.
pub depth: UInt,
/// Event IDs for the authorization events that would allow this event to be
/// in the room.
pub auth_events: Vec<EventId>,
pub auth_events: Vec<Box<EventId>>,
/// For redaction events, the ID of the event being redacted.
#[serde(skip_serializing_if = "Option::is_none")]
pub redacts: Option<EventId>,
pub redacts: Option<Box<EventId>>,
/// Additional data added by the origin server but not covered by the
/// signatures.

View File

@ -32,7 +32,7 @@ mod tests {
#[test]
fn serialization() {
let room_event = PolicyRuleRoomEvent {
event_id: event_id!("$143273582443PhrSn:example.org"),
event_id: event_id!("$143273582443PhrSn:example.org").to_owned(),
sender: user_id!("@example:example.org"),
origin_server_ts: MilliSecondsSinceUnixEpoch(1_432_735_824_653_u64.try_into().unwrap()),
room_id: room_id!("!jEsUZKDJdhlrceRyVU:example.org"),

View File

@ -37,7 +37,7 @@ impl From<Relation> for ReactionEventContent {
#[serde(tag = "rel_type", rename = "m.annotation")]
pub struct Relation {
/// The event that is being reacted to.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// A string that holds the emoji reaction.
#[serde(rename = "key")]
@ -46,7 +46,7 @@ pub struct Relation {
impl Relation {
/// Creates a new `Relation` with the given event ID and emoji.
pub fn new(event_id: EventId, emoji: String) -> Self {
pub fn new(event_id: Box<EventId>, emoji: String) -> Self {
Self { event_id, emoji }
}
}

View File

@ -19,10 +19,10 @@ use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize, EventContent)]
#[allow(clippy::exhaustive_structs)]
#[ruma_event(type = "m.receipt", kind = EphemeralRoom)]
pub struct ReceiptEventContent(pub BTreeMap<EventId, Receipts>);
pub struct ReceiptEventContent(pub BTreeMap<Box<EventId>, Receipts>);
impl Deref for ReceiptEventContent {
type Target = BTreeMap<EventId, Receipts>;
type Target = BTreeMap<Box<EventId>, Receipts>;
fn deref(&self) -> &Self::Target {
&self.0

View File

@ -51,7 +51,7 @@ mod tests {
alias: Some(room_alias_id!("#somewhere:localhost")),
alt_aliases: Vec::new(),
},
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None,
room_id: room_id!("!dummy:example.com"),

View File

@ -90,12 +90,12 @@ pub struct PreviousRoom {
pub room_id: RoomId,
/// The event ID of the last known event in the old room.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
impl PreviousRoom {
/// Creates a new `PreviousRoom` from the given room and event IDs.
pub fn new(room_id: RoomId, event_id: EventId) -> Self {
pub fn new(room_id: RoomId, event_id: Box<EventId>) -> Self {
Self { room_id, event_id }
}
}

View File

@ -119,7 +119,7 @@ pub enum Relation {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Replacement {
/// The ID of the event being replacing.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
/// A reference to another event.
@ -128,13 +128,13 @@ pub struct Replacement {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Reference {
/// The event we are referencing.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
#[cfg(feature = "unstable-pre-spec")]
impl Reference {
/// Creates a new `Reference` with the given event ID.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}
@ -145,7 +145,7 @@ impl Reference {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Annotation {
/// The event that is being annotated.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The annotation.
pub key: String,
@ -154,7 +154,7 @@ pub struct Annotation {
#[cfg(feature = "unstable-pre-spec")]
impl Annotation {
/// Creates a new `Annotation` with the given event ID and key.
pub fn new(event_id: EventId, key: String) -> Self {
pub fn new(event_id: Box<EventId>, key: String) -> Self {
Self { event_id, key }
}
}
@ -298,7 +298,7 @@ mod tests {
session_id: "session_id".into(),
}),
relates_to: Some(Relation::Reply {
in_reply_to: InReplyTo { event_id: event_id!("$h29iv0s8:example.com") },
in_reply_to: InReplyTo { event_id: event_id!("$h29iv0s8:example.com").to_owned() },
}),
};

View File

@ -93,7 +93,7 @@ impl RoomMessageEventContent {
Self {
relates_to: Some(Relation::Reply {
in_reply_to: InReplyTo { event_id: original_message.event_id().clone() },
in_reply_to: InReplyTo { event_id: original_message.event_id().to_owned() },
}),
..Self::text_plain(body)
}
@ -134,7 +134,7 @@ impl RoomMessageEventContent {
let body = format!("{}\n\n{}", quoted, reply);
Self {
relates_to: Some(Relation::Reply {
in_reply_to: InReplyTo { event_id: original_message.event_id().clone() },
in_reply_to: InReplyTo { event_id: original_message.event_id().to_owned() },
}),
..Self::notice_plain(body)
}
@ -361,12 +361,12 @@ pub enum Relation {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct InReplyTo {
/// The event being replied to.
pub event_id: EventId,
pub event_id: Box<EventId>,
}
impl InReplyTo {
/// Creates a new `InReplyTo` with the given event ID.
pub fn new(event_id: EventId) -> Self {
pub fn new(event_id: Box<EventId>) -> Self {
Self { event_id }
}
}
@ -377,7 +377,7 @@ impl InReplyTo {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Replacement {
/// The ID of the event being replacing.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// New content.
pub new_content: Box<RoomMessageEventContent>,
@ -386,7 +386,7 @@ pub struct Replacement {
#[cfg(feature = "unstable-pre-spec")]
impl Replacement {
/// Creates a new `Replacement` with the given event ID and new content.
pub fn new(event_id: EventId, new_content: Box<RoomMessageEventContent>) -> Self {
pub fn new(event_id: Box<EventId>, new_content: Box<RoomMessageEventContent>) -> Self {
Self { event_id, new_content }
}
}

View File

@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize};
#[ruma_event(type = "m.room.message.feedback", kind = Message)]
pub struct RoomMessageFeedbackEventContent {
/// The event that this feedback is related to.
pub target_event_id: EventId,
pub target_event_id: Box<EventId>,
/// The type of feedback.
#[serde(rename = "type")]
@ -24,8 +24,8 @@ pub struct RoomMessageFeedbackEventContent {
}
impl RoomMessageFeedbackEventContent {
/// Create a `RoomFeedbackEventContent` from the given target event id and feedback type.
pub fn new(target_event_id: EventId, feedback_type: FeedbackType) -> Self {
/// Create a `RoomMessageFeedbackEventContent` from the given target event id and feedback type.
pub fn new(target_event_id: Box<EventId>, feedback_type: FeedbackType) -> Self {
Self { target_event_id, feedback_type }
}
}

View File

@ -134,5 +134,5 @@ enum RelationJsonRepr {
#[derive(Clone, Deserialize, Serialize)]
#[cfg(feature = "unstable-pre-spec")]
struct ReplacementJsonRepr {
event_id: EventId,
event_id: Box<EventId>,
}

View File

@ -41,7 +41,7 @@ mod tests {
fn serialization_with_optional_fields_as_none() {
let name_event = StateEvent {
content: RoomNameEventContent { name: "The room name".try_into().ok() },
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None,
room_id: room_id!("!n8f893n9:example.com"),
@ -70,7 +70,7 @@ mod tests {
fn serialization_with_all_fields() {
let name_event = StateEvent {
content: RoomNameEventContent { name: "The room name".try_into().ok() },
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomNameEventContent { name: "The old name".try_into().ok() }),
room_id: room_id!("!n8f893n9:example.com"),

View File

@ -12,12 +12,12 @@ use serde::{Deserialize, Serialize};
#[ruma_event(type = "m.room.pinned_events", kind = State)]
pub struct RoomPinnedEventsEventContent {
/// An ordered list of event IDs to pin.
pub pinned: Vec<EventId>,
pub pinned: Vec<Box<EventId>>,
}
impl RoomPinnedEventsEventContent {
/// Creates a new `RoomPinnedEventsEventContent` with the given events.
pub fn new(pinned: Vec<EventId>) -> Self {
pub fn new(pinned: Vec<Box<EventId>>) -> Self {
Self { pinned }
}
}

View File

@ -179,7 +179,7 @@ mod tests {
users_default: int!(0),
notifications: NotificationPowerLevels::default(),
},
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None,
room_id: room_id!("!n8f893n9:example.com"),
@ -222,7 +222,7 @@ mod tests {
users_default: int!(23),
notifications: assign!(NotificationPowerLevels::new(), { room: int!(23) }),
},
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomPowerLevelsEventContent {
// Make just one field different so we at least know they're two different objects.

View File

@ -15,10 +15,10 @@ pub struct RoomRedactionEvent {
pub content: RoomRedactionEventContent,
/// The ID of the event that was redacted.
pub redacts: EventId,
pub redacts: Box<EventId>,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -62,10 +62,10 @@ pub struct RedactedRoomRedactionEvent {
pub content: RedactedRoomRedactionEventContent,
/// The ID of the event that was redacted.
pub redacts: Option<EventId>,
pub redacts: Option<Box<EventId>>,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -88,10 +88,10 @@ pub struct SyncRoomRedactionEvent {
pub content: RoomRedactionEventContent,
/// The ID of the event that was redacted.
pub redacts: EventId,
pub redacts: Box<EventId>,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,
@ -131,10 +131,10 @@ pub struct RedactedSyncRoomRedactionEvent {
pub content: RedactedRoomRedactionEventContent,
/// The ID of the event that was redacted.
pub redacts: Option<EventId>,
pub redacts: Option<Box<EventId>>,
/// The globally unique event identifier for the user who sent the event.
pub event_id: EventId,
pub event_id: Box<EventId>,
/// The fully-qualified ID of the user who sent this event.
pub sender: UserId,

View File

@ -50,7 +50,7 @@ fn serialize_custom_message_event() {
},
event_type: "m.room.message".into(),
},
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
room_id: room_id!("!room:room.com"),
sender: user_id!("@carl:example.com"),
@ -90,7 +90,7 @@ fn serialize_custom_state_event() {
},
event_type: "m.made.up".into(),
},
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
prev_content: None,
room_id: room_id!("!roomid:room.com"),

View File

@ -202,7 +202,7 @@ fn message_room_event_deserialization() {
fn message_event_serialization() {
let event = MessageEvent {
content: RoomMessageEventContent::text_plain("test"),
event_id: event_id!("$1234:example.com"),
event_id: event_id!("$1234:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(0)),
room_id: room_id!("!roomid:example.com"),
sender: user_id!("@test:example.com"),
@ -285,7 +285,7 @@ fn alias_event_field_access() {
Ok(AnyRoomEvent::State(state_event))
if state_event.state_key() == ""
&& state_event.room_id() == &room_id!("!room:room.com")
&& state_event.event_id() == &event_id!("$152037280074GZeOm:localhost")
&& state_event.event_id() == event_id!("$152037280074GZeOm:localhost")
&& state_event.sender() == &user_id!("@example:localhost")
);

View File

@ -52,7 +52,7 @@ fn deserialize_ephemeral_typing() {
#[test]
fn ephemeral_serialize_receipt() {
let event_id = event_id!("$h29iv0s8:example.com");
let event_id = event_id!("$h29iv0s8:example.com").to_owned();
let user_id = user_id!("@carl:example.com");
let aliases_event = EphemeralRoomEvent {
@ -104,10 +104,10 @@ fn deserialize_ephemeral_receipt() {
AnyEphemeralRoomEvent::Receipt(EphemeralRoomEvent {
content: ReceiptEventContent(receipts),
room_id,
}) if !receipts.is_empty() && receipts.contains_key(&event_id)
}) if !receipts.is_empty() && receipts.contains_key(event_id)
&& room_id == room_id!("!roomid:room.com")
&& receipts
.get(&event_id)
.get(event_id)
.map(|r| r.get(&ReceiptType::Read).unwrap().get(&user_id).unwrap())
.map(|r| r.ts)
.unwrap()

View File

@ -86,7 +86,7 @@ fn serialize_message_event() {
}),
mxc_uri!("mxc://matrix.org/arsrns98rsRSR"),
),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
room_id: room_id!("!roomid:room.com"),
sender: user_id!("@carl:example.com"),

View File

@ -32,7 +32,7 @@ fn message_serialize_sticker() {
}),
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs"),
),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
room_id: room_id!("!roomid:room.com"),
sender: user_id!("@carl:example.com"),

View File

@ -28,7 +28,7 @@ fn serialize_pdu_as_v1() {
let v1_pdu = RoomV1Pdu {
room_id: room_id!("!n8f893n9:example.com"),
event_id: event_id!("$somejoinevent:matrix.org"),
event_id: event_id!("$somejoinevent:matrix.org").to_owned(),
sender: user_id!("@sender:example.com"),
origin: "matrix.org".into(),
origin_server_ts: MilliSecondsSinceUnixEpoch(1_592_050_773_658_u64.try_into().unwrap()),
@ -36,15 +36,15 @@ fn serialize_pdu_as_v1() {
content: to_raw_json_value(&json!({ "testing": 123 })).unwrap(),
state_key: Some("state".into()),
prev_events: vec![(
event_id!("$previousevent:matrix.org"),
event_id!("$previousevent:matrix.org").to_owned(),
EventHash::new("123567".into()),
)],
depth: 2_u32.into(),
auth_events: vec![(
event_id!("$someauthevent:matrix.org"),
event_id!("$someauthevent:matrix.org").to_owned(),
EventHash::new("21389CFEDABC".into()),
)],
redacts: Some(event_id!("$9654:matrix.org")),
redacts: Some(event_id!("$9654:matrix.org").to_owned()),
unsigned,
hashes: EventHash::new("1233543bABACDEF".into()),
signatures,
@ -101,10 +101,10 @@ fn serialize_pdu_as_v3() {
kind: EventType::RoomPowerLevels,
content: to_raw_json_value(&json!({ "testing": 123 })).unwrap(),
state_key: Some("state".into()),
prev_events: vec![event_id!("$previousevent:matrix.org")],
prev_events: vec![event_id!("$previousevent:matrix.org").to_owned()],
depth: 2_u32.into(),
auth_events: vec![event_id!("$someauthevent:matrix.org")],
redacts: Some(event_id!("$9654:matrix.org")),
auth_events: vec![event_id!("$someauthevent:matrix.org").to_owned()],
redacts: Some(event_id!("$9654:matrix.org").to_owned()),
unsigned,
hashes: EventHash::new("1233543bABACDEF".into()),
signatures,
@ -235,7 +235,7 @@ fn deserialize_pdu_as_v3() {
match parsed {
Pdu::RoomV1Pdu(_) => panic!("Matched V1 PDU"),
Pdu::RoomV3Pdu(v3_pdu) => {
assert_eq!(v3_pdu.auth_events.first().unwrap(), &event_id!("$abc123:matrix.org"));
assert_eq!(v3_pdu.auth_events.first().unwrap(), event_id!("$abc123:matrix.org"));
}
#[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"),

View File

@ -23,8 +23,8 @@ fn unsigned() -> RedactedUnsigned {
let mut unsigned = RedactedUnsigned::default();
unsigned.redacted_because = Some(Box::new(SyncRoomRedactionEvent {
content: RoomRedactionEventContent::with_reason("redacted because".into()),
redacts: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com"),
redacts: event_id!("$h29iv0s8:example.com").to_owned(),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
unsigned: Unsigned::default(),
@ -37,7 +37,7 @@ fn unsigned() -> RedactedUnsigned {
fn redacted_message_event_serialize() {
let redacted = RedactedSyncMessageEvent {
content: RedactedRoomMessageEventContent::new(),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
unsigned: RedactedUnsigned::default(),
@ -58,7 +58,7 @@ fn redacted_message_event_serialize() {
fn redacted_aliases_event_serialize_no_content() {
let redacted = RedactedSyncStateEvent {
content: RedactedRoomAliasesEventContent::default(),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
state_key: "".into(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
@ -81,7 +81,7 @@ fn redacted_aliases_event_serialize_no_content() {
fn redacted_aliases_event_serialize_with_content() {
let redacted = RedactedSyncStateEvent {
content: RedactedRoomAliasesEventContent::new_v1(vec![]),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
state_key: "".to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
@ -160,8 +160,8 @@ fn redacted_deserialize_any_room_sync() {
// to the event type string.
unsigned.redacted_because = Some(Box::new(SyncRoomRedactionEvent {
content: RoomRedactionEventContent::with_reason("redacted because".into()),
redacts: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com"),
redacts: event_id!("$h29iv0s8:example.com").to_owned(),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
unsigned: Unsigned::default(),
@ -240,7 +240,7 @@ fn redacted_custom_event_serialize() {
);
let x = from_json_value::<AnyRedactedSyncStateEvent>(redacted).unwrap();
assert_eq!(x.event_id(), &event_id!("$h29iv0s8:example.com"))
assert_eq!(x.event_id(), event_id!("$h29iv0s8:example.com"))
}
#[test]
@ -249,7 +249,7 @@ fn redacted_custom_event_deserialize() {
let redacted = RedactedSyncStateEvent {
content: RedactedCustomEventContent { event_type: "m.made.up".into() },
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
sender: user_id!("@carl:example.com"),
state_key: "hello there".into(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
@ -286,8 +286,8 @@ fn redact_method_properly_redacts() {
let redaction = SyncRoomRedactionEvent {
content: RoomRedactionEventContent::with_reason("redacted because".into()),
redacts: event_id!("$143273582443PhrSn:example.com"),
event_id: event_id!("$h29iv0s8:example.com"),
redacts: event_id!("$143273582443PhrSn:example.com").to_owned(),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
sender: user_id!("@carl:example.com"),
unsigned: Unsigned::default(),

View File

@ -28,8 +28,8 @@ fn redaction() -> JsonValue {
fn serialize_redaction() {
let aliases_event = RoomRedactionEvent {
content: RoomRedactionEventContent::with_reason("being a turd".into()),
redacts: event_id!("$nomore:example.com"),
event_id: event_id!("$h29iv0s8:example.com"),
redacts: event_id!("$nomore:example.com").to_owned(),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
room_id: room_id!("!roomid:room.com"),
sender: user_id!("@carl:example.com"),

View File

@ -40,7 +40,7 @@ fn serialization() {
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd"),
None,
))),
event_id: event_id!("$143273582443PhrSn:example.org"),
event_id: event_id!("$143273582443PhrSn:example.org").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10_000)),
room_id: room_id!("!testroomid:example.org"),
sender: user_id!("@user:example.org"),
@ -203,7 +203,9 @@ fn relates_to_content_serialization() {
let message_event_content =
assign!(RoomMessageEventContent::text_plain("> <@test:example.com> test\n\ntest reply"), {
relates_to: Some(Relation::Reply {
in_reply_to: InReplyTo::new(event_id!("$15827405538098VGFWH:example.com")),
in_reply_to: InReplyTo::new(
event_id!("$15827405538098VGFWH:example.com").to_owned(),
),
}),
});

View File

@ -37,7 +37,7 @@ fn aliases_event_with_prev_content() -> JsonValue {
fn serialize_aliases_with_prev_content() {
let aliases_event = StateEvent {
content: RoomAliasesEventContent::new(vec![room_alias_id!("#somewhere:localhost")]),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomAliasesEventContent::new(vec![room_alias_id!("#inner:localhost")])),
room_id: room_id!("!roomid:room.com"),
@ -56,7 +56,7 @@ fn serialize_aliases_with_prev_content() {
fn serialize_aliases_without_prev_content() {
let aliases_event = StateEvent {
content: RoomAliasesEventContent::new(vec![room_alias_id!("#somewhere:localhost")]),
event_id: event_id!("$h29iv0s8:example.com"),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None,
room_id: room_id!("!roomid:room.com"),

View File

@ -12,7 +12,7 @@ use ruma_identifiers::{EventId, RoomId, UserId};
#[derive(Clone, Debug, Event)]
pub struct StateEvent<C: StateEventContent> {
pub content: C,
pub event_id: EventId,
pub event_id: Box<EventId>,
pub sender: UserId,
pub origin_server_ts: MilliSecondsSinceUnixEpoch,
pub room_id: RoomId,

View File

@ -24,7 +24,7 @@ ruma_api! {
/// The event IDs to backfill from.
#[ruma_api(query)]
pub v: &'a [EventId],
pub v: &'a [Box<EventId>],
/// The maximum number of PDUs to retrieve, including the given events.
#[ruma_api(query)]
@ -48,7 +48,7 @@ impl<'a> Request<'a> {
/// * the given room id.
/// * the event IDs to backfill from.
/// * the maximum number of PDUs to retrieve, including the given events.
pub fn new(room_id: &'a RoomId, v: &'a [EventId], limit: UInt) -> Self {
pub fn new(room_id: &'a RoomId, v: &'a [Box<EventId>], limit: UInt) -> Self {
Self { room_id, v, limit }
}
}

View File

@ -36,10 +36,10 @@ ruma_api! {
/// The latest event IDs that the sender already has.
///
/// These are skipped when retrieving the previous events of `latest_events`.
pub earliest_events: &'a [EventId],
pub earliest_events: &'a [Box<EventId>],
/// The event IDs to retrieve the previous events for.
pub latest_events: &'a [EventId],
pub latest_events: &'a [Box<EventId>],
}
#[derive(Default)]
@ -53,8 +53,8 @@ impl<'a> Request<'a> {
/// Creates a new `Request` for events in the given room with the given constraints.
pub fn new(
room_id: &'a RoomId,
earliest_events: &'a [EventId],
latest_events: &'a [EventId],
earliest_events: &'a [Box<EventId>],
latest_events: &'a [Box<EventId>],
) -> Self {
Self {
room_id,

View File

@ -26,10 +26,10 @@ ruma_api! {
response: {
/// The full set of authorization events that make up the state of the
/// room, and their authorization events, recursively.
pub auth_chain_ids: Vec<EventId>,
pub auth_chain_ids: Vec<Box<EventId>>,
/// The fully resolved state of the room at the given event.
pub pdu_ids: Vec<EventId>,
pub pdu_ids: Vec<Box<EventId>>,
}
}
@ -42,7 +42,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given auth chain IDs and room state IDs.
pub fn new(auth_chain_ids: Vec<EventId>, pdu_ids: Vec<EventId>) -> Self {
pub fn new(auth_chain_ids: Vec<Box<EventId>>, pdu_ids: Vec<Box<EventId>>) -> Self {
Self { auth_chain_ids, pdu_ids }
}
}

View File

@ -14,7 +14,7 @@ struct WrappedError {
}
pub fn serialize<S>(
response: &BTreeMap<EventId, Result<(), String>>,
response: &BTreeMap<Box<EventId>, Result<(), String>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
@ -33,16 +33,17 @@ where
map.end()
}
#[allow(clippy::type_complexity)]
pub fn deserialize<'de, D>(
deserializer: D,
) -> Result<BTreeMap<EventId, Result<(), String>>, D::Error>
) -> Result<BTreeMap<Box<EventId>, Result<(), String>>, D::Error>
where
D: Deserializer<'de>,
{
struct PduProcessResponseVisitor;
impl<'de> Visitor<'de> for PduProcessResponseVisitor {
type Value = BTreeMap<EventId, Result<(), String>>;
type Value = BTreeMap<Box<EventId>, Result<(), String>>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("A map of EventIds to a map of optional errors")
@ -54,7 +55,7 @@ where
{
let mut map = BTreeMap::new();
while let Some((key, value)) = access.next_entry::<EventId, WrappedError>()? {
while let Some((key, value)) = access.next_entry::<Box<EventId>, WrappedError>()? {
let v = match value.error {
None => Ok(()),
Some(error) => Err(error),
@ -79,8 +80,11 @@ mod tests {
#[test]
fn serialize_error() {
let mut response: BTreeMap<EventId, Result<(), String>> = BTreeMap::new();
response.insert(event_id!("$someevent:matrix.org"), Err("Some processing error.".into()));
let mut response: BTreeMap<Box<EventId>, Result<(), String>> = BTreeMap::new();
response.insert(
event_id!("$someevent:matrix.org").to_owned(),
Err("Some processing error.".into()),
);
let serialized = serialize(&response, JsonSerializer).unwrap();
let json = json!({
@ -91,8 +95,8 @@ mod tests {
#[test]
fn serialize_ok() {
let mut response: BTreeMap<EventId, Result<(), String>> = BTreeMap::new();
response.insert(event_id!("$someevent:matrix.org"), Ok(()));
let mut response: BTreeMap<Box<EventId>, Result<(), String>> = BTreeMap::new();
response.insert(event_id!("$someevent:matrix.org").to_owned(), Ok(()));
let serialized = serialize(&response, serde_json::value::Serializer).unwrap();
let json = json!({
@ -110,7 +114,7 @@ mod tests {
let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org");
let event_response = response.get(&event_id).unwrap().clone().unwrap_err();
let event_response = response.get(event_id).unwrap().clone().unwrap_err();
assert_eq!(event_response, "Some processing error.");
}
@ -123,7 +127,7 @@ mod tests {
let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org");
assert!(response.get(&event_id).unwrap().is_ok());
assert!(response.get(event_id).unwrap().is_ok());
}
#[test]
@ -135,7 +139,7 @@ mod tests {
let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org");
let event_response = response.get(&event_id).unwrap().clone().unwrap_err();
let event_response = response.get(event_id).unwrap().clone().unwrap_err();
assert_eq!(event_response, "");
}
@ -145,6 +149,6 @@ mod tests {
"$someevent:matrix.org": {}
});
let response = deserialize(json).unwrap();
assert!(response.get(&event_id!("$someevent:matrix.org")).unwrap().is_ok());
assert!(response.get(event_id!("$someevent:matrix.org")).unwrap().is_ok());
}
}

View File

@ -167,12 +167,12 @@ pub struct ReceiptData {
pub data: Receipt,
/// The extremity event ID the user has read up to.
pub event_ids: Vec<EventId>,
pub event_ids: Vec<Box<EventId>>,
}
impl ReceiptData {
/// Creates a new `ReceiptData`.
pub fn new(data: Receipt, event_ids: Vec<EventId>) -> Self {
pub fn new(data: Receipt, event_ids: Vec<Box<EventId>>) -> Self {
Self { data, event_ids }
}
}

View File

@ -49,7 +49,7 @@ ruma_api! {
response: {
/// Map of event IDs and response for each PDU given in the request.
#[serde(with = "crate::serde::pdu_process_response")]
pub pdus: BTreeMap<EventId, Result<(), String>>,
pub pdus: BTreeMap<Box<EventId>, Result<(), String>>,
}
}
@ -68,7 +68,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given PDUs.
pub fn new(pdus: BTreeMap<EventId, Result<(), String>>) -> Self {
pub fn new(pdus: BTreeMap<Box<EventId>, Result<(), String>>) -> Self {
Self { pdus }
}
}

View File

@ -43,7 +43,7 @@ pub fn event_id(input: TokenStream) -> TokenStream {
assert!(event_id::validate(&id.value()).is_ok(), "Invalid event id");
let output = quote! {
<#dollar_crate::EventId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
<&#dollar_crate::EventId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
};
output.into()

View File

@ -1,16 +1,11 @@
use std::num::NonZeroU8;
use crate::{validate_delimited_id, Error};
use crate::{parse_id, Error};
pub fn validate(s: &str) -> Result<(), Error> {
if s.contains(':') {
validate_delimited_id(s, &['$'])?;
} else if !s.starts_with('$') {
return Err(Error::MissingLeadingSigil);
}
pub fn validate(s: &str) -> Result<Option<NonZeroU8>, Error> {
Ok(match s.contains(':') {
true => Some(parse_id(s, &['$'])?),
false => {
if !s.starts_with('$') {
return Err(Error::MissingLeadingSigil);
}
None
}
})
Ok(())
}

View File

@ -44,3 +44,9 @@ fn parse_id(id: &str, valid_sigils: &[char]) -> Result<NonZeroU8, Error> {
server_name::validate(&id[colon_idx + 1..])?;
Ok(NonZeroU8::new(colon_idx as u8).unwrap())
}
/// Checks an identifier that contains a localpart and hostname for validity.
fn validate_delimited_id(id: &str, valid_sigils: &[char]) -> Result<(), Error> {
parse_id(id, valid_sigils)?;
Ok(())
}

View File

@ -1,52 +1,46 @@
//! Matrix event identifiers.
use std::{convert::TryFrom, fmt, num::NonZeroU8};
use std::convert::TryInto;
use ruma_identifiers_validation::event_id::validate;
use crate::ServerName;
/// A Matrix event ID.
///
/// An `EventId` is generated randomly or converted from a string slice, and can be converted back
/// into a string as needed.
///
/// # Room versions
///
/// Matrix specifies multiple [room versions](https://matrix.org/docs/spec/#room-versions) and the
/// format of event identifiers differ between them. The original format used by room versions 1
/// and 2 uses a short pseudorandom "localpart" followed by the hostname and port of the
/// originating homeserver. Later room versions change event identifiers to be a hash of the event
/// encoded with Base64. Some of the methods provided by `EventId` are only relevant to the
/// original event format.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::EventId;
/// // Original format
/// assert_eq!(
/// EventId::try_from("$h29iv0s8:example.com").unwrap().as_ref(),
/// "$h29iv0s8:example.com"
/// );
/// // Room version 3 format
/// assert_eq!(
/// EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap().as_ref(),
/// "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
/// );
/// // Room version 4 format
/// assert_eq!(
/// EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap().as_ref(),
/// "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
/// );
/// ```
#[derive(Clone)]
pub struct EventId {
full_id: Box<str>,
colon_idx: Option<NonZeroU8>,
}
impl fmt::Debug for EventId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.full_id.fmt(f)
}
opaque_identifier_validated! {
/// A Matrix event ID.
///
/// An `EventId` is generated randomly or converted from a string slice, and can be converted
/// back into a string as needed.
///
/// # Room versions
///
/// Matrix specifies multiple [room versions](https://matrix.org/docs/spec/#room-versions) and
/// the format of event identifiers differ between them. The original format used by room
/// versions 1 and 2 uses a short pseudorandom "localpart" followed by the hostname and port of
/// the originating homeserver. Later room versions change event identifiers to be a hash of the
/// event encoded with Base64. Some of the methods provided by `EventId` are only relevant to
/// the original event format.
///
/// ```
/// # use std::convert::TryFrom;
/// # use ruma_identifiers::EventId;
/// // Original format
/// assert_eq!(
/// <&EventId>::try_from("$h29iv0s8:example.com").unwrap(),
/// "$h29iv0s8:example.com"
/// );
/// // Room version 3 format
/// assert_eq!(
/// <&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap(),
/// "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
/// );
/// // Room version 4 format
/// assert_eq!(
/// <&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap(),
/// "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
/// );
/// ```
pub type EventId [ validate ];
}
impl EventId {
@ -56,12 +50,8 @@ impl EventId {
/// This should only be used for events in the original format as used by Matrix room versions
/// 1 and 2.
#[cfg(feature = "rand")]
pub fn new(server_name: &ServerName) -> Self {
use crate::generate_localpart;
let full_id = format!("${}:{}", generate_localpart(18), server_name).into();
Self { full_id, colon_idx: NonZeroU8::new(19) }
pub fn new(server_name: &ServerName) -> Box<Self> {
Self::from_owned(format!("${}:{}", crate::generate_localpart(18), server_name).into())
}
/// Returns the event's unique ID.
@ -70,37 +60,22 @@ impl EventId {
/// "localpart" that precedes the homeserver. For later formats, this is the entire ID without
/// the leading `$` sigil.
pub fn localpart(&self) -> &str {
let idx = match self.colon_idx {
Some(idx) => idx.get() as usize,
None => self.full_id.len(),
};
&self.full_id[1..idx]
let idx = self.colon_idx().unwrap_or_else(|| self.as_str().len());
&self.as_str()[1..idx]
}
/// Returns the server name of the event ID.
///
/// Only applicable to events in the original format as used by Matrix room versions 1 and 2.
pub fn server_name(&self) -> Option<&ServerName> {
self.colon_idx
.map(|idx| <&ServerName>::try_from(&self.full_id[idx.get() as usize + 1..]).unwrap())
self.colon_idx().map(|idx| self.as_str()[idx as usize + 1..].try_into().unwrap())
}
fn colon_idx(&self) -> Option<usize> {
self.as_str().find(':')
}
}
/// Attempts to create a new Matrix event ID from a string representation.
///
/// If using the original event format as used by Matrix room versions 1 and 2, the string must
/// include the leading $ sigil, the localpart, a literal colon, and a valid homeserver hostname.
fn try_from<S>(event_id: S) -> Result<EventId, crate::Error>
where
S: AsRef<str> + Into<Box<str>>,
{
let colon_idx = ruma_identifiers_validation::event_id::validate(event_id.as_ref())?;
Ok(EventId { full_id: event_id.into(), colon_idx })
}
common_impls!(EventId, try_from, "a Matrix event ID");
#[cfg(test)]
mod tests {
use std::convert::TryFrom;
@ -111,9 +86,7 @@ mod tests {
#[test]
fn valid_original_event_id() {
assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com")
.expect("Failed to create EventId.")
.as_ref(),
<&EventId>::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId."),
"$39hvsi03hlne:example.com"
);
}
@ -121,9 +94,8 @@ mod tests {
#[test]
fn valid_base64_event_id() {
assert_eq!(
EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.")
.as_ref(),
<&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId."),
"$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
)
}
@ -131,9 +103,8 @@ mod tests {
#[test]
fn valid_url_safe_base64_event_id() {
assert_eq!(
EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId.")
.as_ref(),
<&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId."),
"$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
)
}
@ -155,7 +126,8 @@ mod tests {
fn serialize_valid_original_event_id() {
assert_eq!(
serde_json::to_string(
&EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
<&EventId>::try_from("$39hvsi03hlne:example.com")
.expect("Failed to create EventId.")
)
.expect("Failed to convert EventId to JSON."),
r#""$39hvsi03hlne:example.com""#
@ -167,7 +139,7 @@ mod tests {
fn serialize_valid_base64_event_id() {
assert_eq!(
serde_json::to_string(
&EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
<&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.")
)
.expect("Failed to convert EventId to JSON."),
@ -180,7 +152,7 @@ mod tests {
fn serialize_valid_url_safe_base64_event_id() {
assert_eq!(
serde_json::to_string(
&EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
<&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId.")
)
.expect("Failed to convert EventId to JSON."),
@ -192,9 +164,9 @@ mod tests {
#[test]
fn deserialize_valid_original_event_id() {
assert_eq!(
serde_json::from_str::<EventId>(r#""$39hvsi03hlne:example.com""#)
serde_json::from_str::<Box<EventId>>(r#""$39hvsi03hlne:example.com""#)
.expect("Failed to convert JSON to EventId"),
EventId::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
<&EventId>::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId.")
);
}
@ -202,9 +174,11 @@ mod tests {
#[test]
fn deserialize_valid_base64_event_id() {
assert_eq!(
serde_json::from_str::<EventId>(r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#)
.expect("Failed to convert JSON to EventId"),
EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
serde_json::from_str::<Box<EventId>>(
r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#
)
.expect("Failed to convert JSON to EventId"),
<&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.")
);
}
@ -213,9 +187,11 @@ mod tests {
#[test]
fn deserialize_valid_url_safe_base64_event_id() {
assert_eq!(
serde_json::from_str::<EventId>(r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#)
.expect("Failed to convert JSON to EventId"),
EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
serde_json::from_str::<Box<EventId>>(
r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#
)
.expect("Failed to convert JSON to EventId"),
<&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId.")
);
}
@ -223,9 +199,8 @@ mod tests {
#[test]
fn valid_original_event_id_with_explicit_standard_port() {
assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:443")
.expect("Failed to create EventId.")
.as_ref(),
<&EventId>::try_from("$39hvsi03hlne:example.com:443")
.expect("Failed to create EventId."),
"$39hvsi03hlne:example.com:443"
);
}
@ -233,9 +208,8 @@ mod tests {
#[test]
fn valid_original_event_id_with_non_standard_port() {
assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:5000")
.expect("Failed to create EventId.")
.as_ref(),
<&EventId>::try_from("$39hvsi03hlne:example.com:5000")
.expect("Failed to create EventId."),
"$39hvsi03hlne:example.com:5000"
);
}
@ -243,7 +217,7 @@ mod tests {
#[test]
fn missing_original_event_id_sigil() {
assert_eq!(
EventId::try_from("39hvsi03hlne:example.com").unwrap_err(),
<&EventId>::try_from("39hvsi03hlne:example.com").unwrap_err(),
Error::MissingLeadingSigil
);
}
@ -251,7 +225,7 @@ mod tests {
#[test]
fn missing_base64_event_id_sigil() {
assert_eq!(
EventId::try_from("acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap_err(),
<&EventId>::try_from("acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap_err(),
Error::MissingLeadingSigil
);
}
@ -259,20 +233,20 @@ mod tests {
#[test]
fn missing_url_safe_base64_event_id_sigil() {
assert_eq!(
EventId::try_from("Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap_err(),
<&EventId>::try_from("Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap_err(),
Error::MissingLeadingSigil
);
}
#[test]
fn invalid_event_id_host() {
assert_eq!(EventId::try_from("$39hvsi03hlne:/").unwrap_err(), Error::InvalidServerName);
assert_eq!(<&EventId>::try_from("$39hvsi03hlne:/").unwrap_err(), Error::InvalidServerName);
}
#[test]
fn invalid_event_id_port() {
assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:notaport").unwrap_err(),
<&EventId>::try_from("$39hvsi03hlne:example.com:notaport").unwrap_err(),
Error::InvalidServerName
);
}

View File

@ -363,7 +363,7 @@ mod tests {
let devices = &[device];
let notice = Notification {
event_id: Some(&eid),
event_id: Some(eid),
room_id: Some(&rid),
event_type: Some(&EventType::RoomMessage),
sender: Some(&uid),

View File

@ -261,6 +261,8 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
Some(parse_quote! { ::std::string::String })
} else if last_seg.ident == "ClientSecret"
|| last_seg.ident == "DeviceId"
|| last_seg.ident == "DeviceKeyId"
|| last_seg.ident == "EventId"
|| last_seg.ident == "ServerName"
|| last_seg.ident == "SessionId"
|| last_seg.ident == "RawJsonValue"

View File

@ -176,7 +176,7 @@ pub enum ParseError {
/// For when an event ID, coupled with a specific room version, doesn't have a server name
/// embedded.
#[error("Event Id {0:?} should have a server name for the given room version {1:?}")]
ServerNameFromEventIdByRoomVersion(EventId, RoomVersionId),
ServerNameFromEventIdByRoomVersion(Box<EventId>, RoomVersionId),
/// For when the extracted/"parsed" public key from a PKCS#8 v2 document doesn't match the
/// public key derived from it's private key.
@ -229,7 +229,7 @@ impl ParseError {
event_id: &EventId,
room_version: &RoomVersionId,
) -> Error {
Self::ServerNameFromEventIdByRoomVersion(event_id.clone(), room_version.clone()).into()
Self::ServerNameFromEventIdByRoomVersion(event_id.to_owned(), room_version.clone()).into()
}
pub(crate) fn derived_vs_parsed_mismatch<P: Into<Vec<u8>>, D: Into<Vec<u8>>>(

View File

@ -792,8 +792,8 @@ fn servers_to_check_signatures(
match version {
RoomVersionId::Version1 | RoomVersionId::Version2 => match object.get("event_id") {
Some(CanonicalJsonValue::String(raw_event_id)) => {
let event_id = EventId::from_str(raw_event_id)
.map_err(|e| Error::from(ParseError::EventId(e)))?;
let event_id: Box<EventId> =
raw_event_id.parse().map_err(|e| Error::from(ParseError::EventId(e)))?;
let server_name = event_id
.server_name()

View File

@ -16,7 +16,7 @@ pub trait Event {
pub type StateMap<T> = BTreeMap<(EventType, Option<String>), T>;
/// A mapping of `EventId` to `T`, usually a `StateEvent`.
pub type EventMap<T> = BTreeMap<EventId, T>;
pub type EventMap<T> = BTreeMap<Box<EventId>, T>;
struct StateResolution {
// For now the StateResolution struct is empty. If "caching" `event_map`
@ -30,10 +30,10 @@ impl StateResolution {
pub fn resolve<E: Event>(
room_id: &RoomId,
room_version: &RoomVersionId,
state_sets: &[StateMap<EventId>],
auth_events: Vec<Vec<EventId>>,
state_sets: &[StateMap<Box<EventId>>],
auth_events: Vec<Vec<Box<EventId>>>,
event_map: &mut EventMap<Arc<E>>,
) -> Result<StateMap<EventId>> {;
) -> Result<StateMap<Box<EventId>>> {;
}
```

View File

@ -49,7 +49,7 @@ fn lexico_topo_sort(c: &mut Criterion) {
};
b.iter(|| {
let _ = state_res::lexicographical_topological_sort(&graph, |id| {
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.to_owned()))
});
})
});
@ -104,7 +104,7 @@ fn resolve_deeper_event_set(c: &mut Criterion) {
.map(|ev| {
(
(ev.event_type().to_owned(), ev.state_key().unwrap().to_owned()),
ev.event_id().clone(),
ev.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -122,7 +122,7 @@ fn resolve_deeper_event_set(c: &mut Criterion) {
.map(|ev| {
(
(ev.event_type().to_owned(), ev.state_key().unwrap().to_owned()),
ev.event_id().clone(),
ev.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -161,7 +161,7 @@ criterion_main!(benches);
// IMPLEMENTATION DETAILS AHEAD
//
/////////////////////////////////////////////////////////////////////*/
struct TestStore<E: Event>(HashMap<EventId, Arc<E>>);
struct TestStore<E: Event>(HashMap<Box<EventId>, Arc<E>>);
#[allow(unused)]
impl<E: Event> TestStore<E> {
@ -173,7 +173,7 @@ impl<E: Event> TestStore<E> {
}
/// Returns the events that correspond to the `event_ids` sorted in the same order.
fn get_events(&self, room_id: &RoomId, event_ids: &[EventId]) -> Result<Vec<Arc<E>>> {
fn get_events(&self, room_id: &RoomId, event_ids: &[Box<EventId>]) -> Result<Vec<Arc<E>>> {
let mut events = vec![];
for id in event_ids {
events.push(self.get_event(room_id, id)?);
@ -185,8 +185,8 @@ impl<E: Event> TestStore<E> {
fn auth_event_ids(
&self,
room_id: &RoomId,
event_ids: Vec<EventId>,
) -> Result<HashSet<EventId>> {
event_ids: Vec<Box<EventId>>,
) -> Result<HashSet<Box<EventId>>> {
let mut result = HashSet::new();
let mut stack = event_ids;
@ -201,18 +201,19 @@ impl<E: Event> TestStore<E> {
let event = self.get_event(room_id, &ev_id)?;
stack.extend(event.auth_events().cloned());
stack.extend(event.auth_events().map(ToOwned::to_owned));
}
Ok(result)
}
/// Returns a Vec<EventId> representing the difference in auth chains of the given `events`.
/// Returns a Vec<Box<EventId>> representing the difference in auth chains of the given
/// `events`.
fn auth_chain_diff(
&self,
room_id: &RoomId,
event_ids: Vec<Vec<EventId>>,
) -> Result<Vec<EventId>> {
event_ids: Vec<Vec<Box<EventId>>>,
) -> Result<Vec<Box<EventId>>> {
let mut auth_chain_sets = vec![];
for ids in event_ids {
// TODO state store `auth_event_ids` returns self in the event ids list
@ -225,7 +226,7 @@ impl<E: Event> TestStore<E> {
let common = auth_chain_sets
.iter()
.skip(1)
.fold(first, |a, b| a.intersection(b).cloned().collect::<HashSet<EventId>>());
.fold(first, |a, b| a.intersection(b).cloned().collect::<HashSet<Box<EventId>>>());
Ok(auth_chain_sets.into_iter().flatten().filter(|id| !common.contains(id)).collect())
} else {
@ -235,8 +236,11 @@ impl<E: Event> TestStore<E> {
}
impl TestStore<StateEvent> {
fn set_up(&mut self) -> (StateMap<EventId>, StateMap<EventId>, StateMap<EventId>) {
let create_event = to_pdu_event::<EventId>(
#[allow(clippy::type_complexity)]
fn set_up(
&mut self,
) -> (StateMap<Box<EventId>>, StateMap<Box<EventId>>, StateMap<Box<EventId>>) {
let create_event = to_pdu_event::<&EventId>(
"CREATE",
alice(),
EventType::RoomCreate,
@ -245,7 +249,7 @@ impl TestStore<StateEvent> {
&[],
&[],
);
let cre = create_event.event_id().clone();
let cre = create_event.event_id().to_owned();
self.0.insert(cre.clone(), Arc::clone(&create_event));
let alice_mem = to_pdu_event(
@ -257,7 +261,7 @@ impl TestStore<StateEvent> {
&[cre.clone()],
&[cre.clone()],
);
self.0.insert(alice_mem.event_id().clone(), Arc::clone(&alice_mem));
self.0.insert(alice_mem.event_id().to_owned(), Arc::clone(&alice_mem));
let join_rules = to_pdu_event(
"IJR",
@ -265,10 +269,10 @@ impl TestStore<StateEvent> {
EventType::RoomJoinRules,
Some(""),
to_raw_json_value(&RoomJoinRulesEventContent::new(JoinRule::Public)).unwrap(),
&[cre.clone(), alice_mem.event_id().clone()],
&[alice_mem.event_id().clone()],
&[cre.clone(), alice_mem.event_id().to_owned()],
&[alice_mem.event_id().to_owned()],
);
self.0.insert(join_rules.event_id().clone(), join_rules.clone());
self.0.insert(join_rules.event_id().to_owned(), join_rules.clone());
// Bob and Charlie join at the same time, so there is a fork
// this will be represented in the state_sets when we resolve
@ -278,10 +282,10 @@ impl TestStore<StateEvent> {
EventType::RoomMember,
Some(bob().to_string().as_str()),
member_content_join(),
&[cre.clone(), join_rules.event_id().clone()],
&[join_rules.event_id().clone()],
&[cre.clone(), join_rules.event_id().to_owned()],
&[join_rules.event_id().to_owned()],
);
self.0.insert(bob_mem.event_id().clone(), bob_mem.clone());
self.0.insert(bob_mem.event_id().to_owned(), bob_mem.clone());
let charlie_mem = to_pdu_event(
"IMC",
@ -289,17 +293,17 @@ impl TestStore<StateEvent> {
EventType::RoomMember,
Some(charlie().to_string().as_str()),
member_content_join(),
&[cre, join_rules.event_id().clone()],
&[join_rules.event_id().clone()],
&[cre, join_rules.event_id().to_owned()],
&[join_rules.event_id().to_owned()],
);
self.0.insert(charlie_mem.event_id().clone(), charlie_mem.clone());
self.0.insert(charlie_mem.event_id().to_owned(), charlie_mem.clone());
let state_at_bob = [&create_event, &alice_mem, &join_rules, &bob_mem]
.iter()
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -309,7 +313,7 @@ impl TestStore<StateEvent> {
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -319,7 +323,7 @@ impl TestStore<StateEvent> {
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -328,11 +332,11 @@ impl TestStore<StateEvent> {
}
}
fn event_id(id: &str) -> EventId {
fn event_id(id: &str) -> Box<EventId> {
if id.contains('$') {
return EventId::try_from(id).unwrap();
return id.try_into().unwrap();
}
EventId::try_from(format!("${}:foo", id)).unwrap()
format!("${}:foo", id).try_into().unwrap()
}
fn alice() -> UserId {
@ -384,7 +388,7 @@ where
let state_key = state_key.map(ToOwned::to_owned);
Arc::new(StateEvent {
event_id: EventId::try_from(id).unwrap(),
event_id: id.try_into().unwrap(),
rest: Pdu::RoomV3Pdu(RoomV3Pdu {
room_id: room_id(),
sender,
@ -407,9 +411,9 @@ where
// all graphs start with these input events
#[allow(non_snake_case)]
fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
fn INITIAL_EVENTS() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"CREATE",
alice(),
EventType::RoomCreate,
@ -463,7 +467,7 @@ fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
&["CREATE", "IJR", "IPOWER"],
&["IMB"],
),
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"START",
charlie(),
EventType::RoomTopic,
@ -472,7 +476,7 @@ fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
&[],
&[],
),
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"END",
charlie(),
EventType::RoomTopic,
@ -483,13 +487,13 @@ fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
),
]
.into_iter()
.map(|ev| (ev.event_id().clone(), ev))
.map(|ev| (ev.event_id().to_owned(), ev))
.collect()
}
// all graphs start with these input events
#[allow(non_snake_case)]
fn BAN_STATE_SET() -> HashMap<EventId, Arc<StateEvent>> {
fn BAN_STATE_SET() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![
to_pdu_event(
"PA",
@ -529,7 +533,7 @@ fn BAN_STATE_SET() -> HashMap<EventId, Arc<StateEvent>> {
),
]
.into_iter()
.map(|ev| (ev.event_id().clone(), ev))
.map(|ev| (ev.event_id().to_owned(), ev))
.collect()
}
@ -602,8 +606,8 @@ mod event {
fn prev_events(&self) -> Box<dyn DoubleEndedIterator<Item = &EventId> + '_> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter()),
Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| &**id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter().map(|id| &**id)),
#[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"),
}
@ -611,8 +615,8 @@ mod event {
fn auth_events(&self) -> Box<dyn DoubleEndedIterator<Item = &EventId> + '_> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter()),
Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| &**id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter().map(|id| &**id)),
#[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"),
}
@ -620,8 +624,8 @@ mod event {
fn redacts(&self) -> Option<&EventId> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => ev.redacts.as_ref(),
Pdu::RoomV3Pdu(ev) => ev.redacts.as_ref(),
Pdu::RoomV1Pdu(ev) => ev.redacts.as_deref(),
Pdu::RoomV3Pdu(ev) => ev.redacts.as_deref(),
#[cfg(not(feature = "unstable-exhaustive-types"))]
_ => unreachable!("new PDU version"),
}
@ -630,7 +634,7 @@ mod event {
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StateEvent {
pub event_id: EventId,
pub event_id: Box<EventId>,
#[serde(flatten)]
pub rest: Pdu,
}

View File

@ -31,7 +31,7 @@ pub use state_event::Event;
pub type StateMap<T> = HashMap<(EventType, String), T>;
/// A mapping of `EventId` to `T`, usually a `ServerPdu`.
type EventMap<T> = HashMap<EventId, T>;
type EventMap<T> = HashMap<Box<EventId>, T>;
/// Resolve sets of state events as they come in.
///
@ -56,12 +56,12 @@ type EventMap<T> = HashMap<EventId, T>;
pub fn resolve<'a, E, SSI>(
room_version: &RoomVersionId,
state_sets: impl IntoIterator<IntoIter = SSI>,
auth_chain_sets: Vec<HashSet<EventId>>,
auth_chain_sets: Vec<HashSet<Box<EventId>>>,
fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<StateMap<EventId>>
) -> Result<StateMap<Box<EventId>>>
where
E: Event + Clone,
SSI: Iterator<Item = &'a StateMap<EventId>> + Clone,
SSI: Iterator<Item = &'a StateMap<Box<EventId>>> + Clone,
{
info!("State resolution starting");
@ -124,7 +124,7 @@ where
// auth
let events_to_resolve = all_conflicted
.iter()
.filter(|id| !deduped_power_ev.contains(id))
.filter(|&id| !deduped_power_ev.contains(id))
.cloned()
.collect::<Vec<_>>();
@ -136,7 +136,8 @@ where
debug!("power event: {:?}", power_event);
let sorted_left_events = mainline_sort(&events_to_resolve, power_event, &fetch_event)?;
let sorted_left_events =
mainline_sort(&events_to_resolve, power_event.map(|id| &**id), &fetch_event)?;
trace!("events left, sorted: {:?}", sorted_left_events);
@ -161,8 +162,8 @@ where
/// exactly one eventId. This includes missing events, if one state_set includes an event that none
/// of the other have this is a conflicting event.
fn separate<'a>(
state_sets_iter: impl Iterator<Item = &'a StateMap<EventId>> + Clone,
) -> (StateMap<EventId>, StateMap<Vec<EventId>>) {
state_sets_iter: impl Iterator<Item = &'a StateMap<Box<EventId>>> + Clone,
) -> (StateMap<Box<EventId>>, StateMap<Vec<Box<EventId>>>) {
let mut unconflicted_state = StateMap::new();
let mut conflicted_state = StateMap::new();
@ -186,10 +187,12 @@ fn separate<'a>(
}
/// Returns a Vec of deduped EventIds that appear in some chains but not others.
fn get_auth_chain_diff(auth_chain_sets: Vec<HashSet<EventId>>) -> impl Iterator<Item = EventId> {
fn get_auth_chain_diff(
auth_chain_sets: Vec<HashSet<Box<EventId>>>,
) -> impl Iterator<Item = Box<EventId>> {
let num_sets = auth_chain_sets.len();
let mut id_counts: HashMap<EventId, usize> = HashMap::new();
let mut id_counts: HashMap<Box<EventId>, usize> = HashMap::new();
for id in auth_chain_sets.into_iter().flatten() {
*id_counts.entry(id).or_default() += 1;
}
@ -205,10 +208,10 @@ fn get_auth_chain_diff(auth_chain_sets: Vec<HashSet<EventId>>) -> impl Iterator<
/// The power level is negative because a higher power level is equated to an earlier (further back
/// in time) origin server timestamp.
fn reverse_topological_power_sort<E: Event>(
events_to_sort: Vec<EventId>,
auth_diff: &HashSet<EventId>,
events_to_sort: Vec<Box<EventId>>,
auth_diff: &HashSet<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<Vec<EventId>> {
) -> Result<Vec<Box<EventId>>> {
debug!("reverse topological sort of power events");
let mut graph = HashMap::new();
@ -242,7 +245,7 @@ fn reverse_topological_power_sort<E: Event>(
// This return value is the key used for sorting events,
// events are then sorted by power level, time,
// and lexically by event_id.
Ok((-*pl, ev.origin_server_ts(), ev.event_id().clone()))
Ok((-*pl, ev.origin_server_ts(), ev.event_id().to_owned()))
})
}
@ -251,11 +254,11 @@ fn reverse_topological_power_sort<E: Event>(
/// `key_fn` is used as a tie breaker. The tie breaker happens based on power level, age, and
/// event_id.
pub fn lexicographical_topological_sort<F>(
graph: &HashMap<EventId, HashSet<EventId>>,
graph: &HashMap<Box<EventId>, HashSet<Box<EventId>>>,
key_fn: F,
) -> Result<Vec<EventId>>
) -> Result<Vec<Box<EventId>>>
where
F: Fn(&EventId) -> Result<(Int, MilliSecondsSinceUnixEpoch, EventId)>,
F: Fn(&EventId) -> Result<(Int, MilliSecondsSinceUnixEpoch, Box<EventId>)>,
{
info!("starting lexicographical topological sort");
// NOTE: an event that has no incoming edges happened most recently,
@ -271,7 +274,7 @@ where
// The number of events that depend on the given event (the EventId key)
// How many events reference this event in the DAG as a parent
let mut reverse_graph: HashMap<&EventId, HashSet<&EventId>> = HashMap::new();
let mut reverse_graph: HashMap<_, HashSet<_>> = HashMap::new();
// Vec of nodes that have zero out degree, least recent events.
let mut zero_outdegree = vec![];
@ -295,8 +298,7 @@ where
let mut sorted = vec![];
// Destructure the `Reverse` and take the smallest `node` each time
while let Some(Reverse((_, node))) = heap.pop() {
let node: &EventId = node;
for parent in reverse_graph.get(node).expect("EventId in heap is also in reverse_graph") {
for &parent in reverse_graph.get(node).expect("EventId in heap is also in reverse_graph") {
// The number of outgoing edges this node has
let out = outdegree_map
.get_mut(parent)
@ -310,7 +312,7 @@ where
}
// synapse yields we push then return the vec
sorted.push(node.clone());
sorted.push(node.to_owned());
}
Ok(sorted)
@ -373,16 +375,16 @@ fn get_power_level_for_sender<E: Event>(
/// ## Returns
///
/// The `unconflicted_state` combined with the newly auth'ed events. So any event that fails the
/// `event_auth::auth_check` will be excluded from the returned `StateMap<EventId>`.
/// `event_auth::auth_check` will be excluded from the returned `StateMap<Box<EventId>>`.
///
/// For each `events_to_check` event we gather the events needed to auth it from the the
/// `fetch_event` closure and verify each event using the `event_auth::auth_check` function.
fn iterative_auth_check<E: Event + Clone>(
room_version: &RoomVersion,
events_to_check: &[EventId],
unconflicted_state: StateMap<EventId>,
events_to_check: &[Box<EventId>],
unconflicted_state: StateMap<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<StateMap<EventId>> {
) -> Result<StateMap<Box<EventId>>> {
info!("starting iterative auth check");
debug!("performing auth checks on {:?}", events_to_check);
@ -476,10 +478,10 @@ fn iterative_auth_check<E: Event + Clone>(
/// the events before (with the first power level as a parent) will be marked as depth 1. depth 1 is
/// "older" than depth 0.
fn mainline_sort<E: Event>(
to_sort: &[EventId],
to_sort: &[Box<EventId>],
resolved_power_level: Option<&EventId>,
fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<Vec<EventId>> {
) -> Result<Vec<Box<EventId>>> {
debug!("mainline sort of events");
// There are no EventId's to sort, bail.
@ -488,7 +490,7 @@ fn mainline_sort<E: Event>(
}
let mut mainline = vec![];
let mut pl = resolved_power_level.cloned();
let mut pl = resolved_power_level.map(ToOwned::to_owned);
while let Some(p) = pl {
mainline.push(p.clone());
@ -499,7 +501,7 @@ fn mainline_sort<E: Event>(
let ev = fetch_event(aid)
.ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?;
if is_type_and_key(&ev, &EventType::RoomPowerLevels, "") {
pl = Some(aid.clone());
pl = Some(aid.to_owned());
break;
}
}
@ -548,7 +550,7 @@ fn get_mainline_depth<E: Event>(
) -> Result<usize> {
while let Some(sort_ev) = event {
debug!("mainline event_id {}", sort_ev.event_id());
let id = &sort_ev.event_id();
let id = sort_ev.event_id();
if let Some(depth) = mainline_map.get(id) {
return Ok(*depth);
}
@ -568,9 +570,9 @@ fn get_mainline_depth<E: Event>(
}
fn add_event_and_auth_chain_to_graph<E: Event>(
graph: &mut HashMap<EventId, HashSet<EventId>>,
event_id: EventId,
auth_diff: &HashSet<EventId>,
graph: &mut HashMap<Box<EventId>, HashSet<Box<EventId>>>,
event_id: Box<EventId>,
auth_diff: &HashSet<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>,
) {
let mut state = vec![event_id];
@ -580,11 +582,11 @@ fn add_event_and_auth_chain_to_graph<E: Event>(
for aid in fetch_event(&eid).as_ref().map(|ev| ev.auth_events()).into_iter().flatten() {
if auth_diff.contains(aid) {
if !graph.contains_key(aid) {
state.push(aid.clone());
state.push(aid.to_owned());
}
// We just inserted this at the start of the while loop
graph.get_mut(&eid).unwrap().insert(aid.clone());
graph.get_mut(&eid).unwrap().insert(aid.to_owned());
}
}
}
@ -690,8 +692,10 @@ mod tests {
let power_level = resolved_power.get(&(EventType::RoomPowerLevels, "".to_owned()));
let sorted_event_ids =
crate::mainline_sort(&events_to_sort, power_level, |id| events.get(id).map(Arc::clone))
.unwrap();
crate::mainline_sort(&events_to_sort, power_level.map(|id| &**id), |id| {
events.get(id).map(Arc::clone)
})
.unwrap();
assert_eq!(
vec![
@ -1066,7 +1070,7 @@ mod tests {
};
let res = crate::lexicographical_topological_sort(&graph, |id| {
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.to_owned()))
})
.unwrap();
@ -1193,7 +1197,7 @@ mod tests {
}
#[allow(non_snake_case)]
fn BAN_STATE_SET() -> HashMap<EventId, Arc<StateEvent>> {
fn BAN_STATE_SET() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![
to_pdu_event(
"PA",
@ -1238,7 +1242,7 @@ mod tests {
}
#[allow(non_snake_case)]
fn JOIN_RULE() -> HashMap<EventId, Arc<StateEvent>> {
fn JOIN_RULE() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![
to_pdu_event(
"JR",

View File

@ -1,6 +1,6 @@
use std::{
collections::{BTreeMap, HashMap, HashSet},
convert::{TryFrom, TryInto},
convert::TryInto,
sync::{
atomic::{AtomicU64, Ordering::SeqCst},
Arc,
@ -32,15 +32,19 @@ static SERVER_TIMESTAMP: AtomicU64 = AtomicU64::new(0);
pub fn do_check(
events: &[Arc<StateEvent>],
edges: Vec<Vec<EventId>>,
expected_state_ids: Vec<EventId>,
edges: Vec<Vec<Box<EventId>>>,
expected_state_ids: Vec<Box<EventId>>,
) {
// To activate logging use `RUST_LOG=debug cargo t`
let init_events = INITIAL_EVENTS();
let mut store = TestStore(
init_events.values().chain(events).map(|ev| (ev.event_id().clone(), ev.clone())).collect(),
init_events
.values()
.chain(events)
.map(|ev| (ev.event_id().to_owned(), ev.clone()))
.collect(),
);
// This will be lexi_topo_sorted for resolution
@ -51,42 +55,42 @@ pub fn do_check(
// Create the DB of events that led up to this point
// TODO maybe clean up some of these clones it is just tests but...
for ev in init_events.values().chain(events) {
graph.insert(ev.event_id().clone(), HashSet::new());
fake_event_map.insert(ev.event_id().clone(), ev.clone());
graph.insert(ev.event_id().to_owned(), HashSet::new());
fake_event_map.insert(ev.event_id().to_owned(), ev.clone());
}
for pair in INITIAL_EDGES().windows(2) {
if let [a, b] = &pair {
graph.entry(a.clone()).or_insert_with(HashSet::new).insert(b.clone());
graph.entry(a.to_owned()).or_insert_with(HashSet::new).insert(b.clone());
}
}
for edge_list in edges {
for pair in edge_list.windows(2) {
if let [a, b] = &pair {
graph.entry(a.clone()).or_insert_with(HashSet::new).insert(b.clone());
graph.entry(a.to_owned()).or_insert_with(HashSet::new).insert(b.clone());
}
}
}
// event_id -> StateEvent
let mut event_map: HashMap<EventId, Arc<StateEvent>> = HashMap::new();
// event_id -> StateMap<EventId>
let mut state_at_event: HashMap<EventId, StateMap<EventId>> = HashMap::new();
let mut event_map: HashMap<Box<EventId>, Arc<StateEvent>> = HashMap::new();
// event_id -> StateMap<Box<EventId>>
let mut state_at_event: HashMap<Box<EventId>, StateMap<Box<EventId>>> = HashMap::new();
// Resolve the current state and add it to the state_at_event map then continue
// on in "time"
for node in crate::lexicographical_topological_sort(&graph, |id| {
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.clone()))
Ok((int!(0), MilliSecondsSinceUnixEpoch(uint!(0)), id.to_owned()))
})
.unwrap()
{
let fake_event = fake_event_map.get(&node).unwrap();
let event_id = fake_event.event_id().clone();
let event_id = fake_event.event_id().to_owned();
let prev_events = graph.get(&node).unwrap();
let state_before: StateMap<EventId> = if prev_events.is_empty() {
let state_before: StateMap<Box<EventId>> = if prev_events.is_empty() {
HashMap::new()
} else if prev_events.len() == 1 {
state_at_event.get(prev_events.iter().next().unwrap()).unwrap().clone()
@ -126,7 +130,7 @@ pub fn do_check(
let ty = fake_event.event_type().to_owned();
let key = fake_event.state_key().unwrap().to_owned();
state_after.insert((ty, key), event_id.clone());
state_after.insert((ty, key), event_id.to_owned());
let auth_types = auth_types_for_event(
fake_event.event_type(),
@ -146,7 +150,7 @@ pub fn do_check(
// TODO The event is just remade, adding the auth_events and prev_events here
// the `to_pdu_event` was split into `init` and the fn below, could be better
let e = fake_event;
let ev_id = e.event_id().clone();
let ev_id = e.event_id();
let event = to_pdu_event(
e.event_id().as_str(),
e.sender().clone(),
@ -159,10 +163,10 @@ pub fn do_check(
// We have to update our store, an actual user of this lib would
// be giving us state from a DB.
store.0.insert(ev_id.clone(), event.clone());
store.0.insert(ev_id.to_owned(), event.clone());
state_at_event.insert(node, state_after);
event_map.insert(event_id.clone(), Arc::clone(store.0.get(&ev_id).unwrap()));
event_map.insert(event_id.to_owned(), Arc::clone(store.0.get(ev_id).unwrap()));
}
let mut expected_state = StateMap::new();
@ -180,10 +184,10 @@ pub fn do_check(
expected_state.insert(key, node);
}
let start_state = state_at_event.get(&event_id!("$START:foo")).unwrap();
let start_state = state_at_event.get(event_id!("$START:foo")).unwrap();
let end_state = state_at_event
.get(&event_id!("$END:foo"))
.get(event_id!("$END:foo"))
.unwrap()
.iter()
.filter(|(k, v)| {
@ -195,13 +199,13 @@ pub fn do_check(
&& **k != (EventType::RoomMessage, "dummy".to_owned())
})
.map(|(k, v)| (k.clone(), v.clone()))
.collect::<StateMap<EventId>>();
.collect::<StateMap<Box<EventId>>>();
assert_eq!(expected_state, end_state);
}
#[allow(clippy::exhaustive_structs)]
pub struct TestStore<E: Event>(pub HashMap<EventId, Arc<E>>);
pub struct TestStore<E: Event>(pub HashMap<Box<EventId>, Arc<E>>);
impl<E: Event> TestStore<E> {
pub fn get_event(&self, _: &RoomId, event_id: &EventId) -> Result<Arc<E>> {
@ -215,8 +219,8 @@ impl<E: Event> TestStore<E> {
pub fn auth_event_ids(
&self,
room_id: &RoomId,
event_ids: Vec<EventId>,
) -> Result<HashSet<EventId>> {
event_ids: Vec<Box<EventId>>,
) -> Result<HashSet<Box<EventId>>> {
let mut result = HashSet::new();
let mut stack = event_ids;
@ -230,7 +234,7 @@ impl<E: Event> TestStore<E> {
let event = self.get_event(room_id, &ev_id)?;
stack.extend(event.auth_events().cloned());
stack.extend(event.auth_events().map(ToOwned::to_owned));
}
Ok(result)
@ -238,9 +242,12 @@ impl<E: Event> TestStore<E> {
}
// A StateStore implementation for testing
#[allow(clippy::type_complexity)]
impl TestStore<StateEvent> {
pub fn set_up(&mut self) -> (StateMap<EventId>, StateMap<EventId>, StateMap<EventId>) {
let create_event = to_pdu_event::<EventId>(
pub fn set_up(
&mut self,
) -> (StateMap<Box<EventId>>, StateMap<Box<EventId>>, StateMap<Box<EventId>>) {
let create_event = to_pdu_event::<&EventId>(
"CREATE",
alice(),
EventType::RoomCreate,
@ -249,7 +256,7 @@ impl TestStore<StateEvent> {
&[],
&[],
);
let cre = create_event.event_id().clone();
let cre = create_event.event_id().to_owned();
self.0.insert(cre.clone(), Arc::clone(&create_event));
let alice_mem = to_pdu_event(
@ -261,7 +268,7 @@ impl TestStore<StateEvent> {
&[cre.clone()],
&[cre.clone()],
);
self.0.insert(alice_mem.event_id().clone(), Arc::clone(&alice_mem));
self.0.insert(alice_mem.event_id().to_owned(), Arc::clone(&alice_mem));
let join_rules = to_pdu_event(
"IJR",
@ -269,10 +276,10 @@ impl TestStore<StateEvent> {
EventType::RoomJoinRules,
Some(""),
to_raw_json_value(&RoomJoinRulesEventContent::new(JoinRule::Public)).unwrap(),
&[cre.clone(), alice_mem.event_id().clone()],
&[alice_mem.event_id().clone()],
&[cre.clone(), alice_mem.event_id().to_owned()],
&[alice_mem.event_id().to_owned()],
);
self.0.insert(join_rules.event_id().clone(), join_rules.clone());
self.0.insert(join_rules.event_id().to_owned(), join_rules.clone());
// Bob and Charlie join at the same time, so there is a fork
// this will be represented in the state_sets when we resolve
@ -282,10 +289,10 @@ impl TestStore<StateEvent> {
EventType::RoomMember,
Some(bob().to_string().as_str()),
member_content_join(),
&[cre.clone(), join_rules.event_id().clone()],
&[join_rules.event_id().clone()],
&[cre.clone(), join_rules.event_id().to_owned()],
&[join_rules.event_id().to_owned()],
);
self.0.insert(bob_mem.event_id().clone(), bob_mem.clone());
self.0.insert(bob_mem.event_id().to_owned(), bob_mem.clone());
let charlie_mem = to_pdu_event(
"IMC",
@ -293,17 +300,17 @@ impl TestStore<StateEvent> {
EventType::RoomMember,
Some(charlie().to_string().as_str()),
member_content_join(),
&[cre, join_rules.event_id().clone()],
&[join_rules.event_id().clone()],
&[cre, join_rules.event_id().to_owned()],
&[join_rules.event_id().to_owned()],
);
self.0.insert(charlie_mem.event_id().clone(), charlie_mem.clone());
self.0.insert(charlie_mem.event_id().to_owned(), charlie_mem.clone());
let state_at_bob = [&create_event, &alice_mem, &join_rules, &bob_mem]
.iter()
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -313,7 +320,7 @@ impl TestStore<StateEvent> {
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -323,7 +330,7 @@ impl TestStore<StateEvent> {
.map(|e| {
(
(e.event_type().to_owned(), e.state_key().unwrap().to_owned()),
e.event_id().clone(),
e.event_id().to_owned(),
)
})
.collect::<StateMap<_>>();
@ -332,11 +339,12 @@ impl TestStore<StateEvent> {
}
}
pub fn event_id(id: &str) -> EventId {
pub fn event_id(id: &str) -> Box<EventId> {
if id.contains('$') {
return EventId::try_from(id).unwrap();
return id.try_into().unwrap();
}
EventId::try_from(format!("${}:foo", id)).unwrap()
format!("${}:foo", id).try_into().unwrap()
}
pub fn alice() -> UserId {
@ -383,7 +391,7 @@ pub fn to_init_pdu_event(
let state_key = state_key.map(ToOwned::to_owned);
Arc::new(StateEvent {
event_id: EventId::try_from(id).unwrap(),
event_id: id.try_into().unwrap(),
rest: Pdu::RoomV3Pdu(RoomV3Pdu {
room_id: room_id(),
sender,
@ -423,7 +431,7 @@ where
let state_key = state_key.map(ToOwned::to_owned);
Arc::new(StateEvent {
event_id: EventId::try_from(id).unwrap(),
event_id: id.try_into().unwrap(),
rest: Pdu::RoomV3Pdu(RoomV3Pdu {
room_id: room_id(),
sender,
@ -446,9 +454,9 @@ where
// all graphs start with these input events
#[allow(non_snake_case)]
pub fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
pub fn INITIAL_EVENTS() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"CREATE",
alice(),
EventType::RoomCreate,
@ -502,7 +510,7 @@ pub fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
&["CREATE", "IJR", "IPOWER"],
&["IMB"],
),
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"START",
charlie(),
EventType::RoomMessage,
@ -511,7 +519,7 @@ pub fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
&[],
&[],
),
to_pdu_event::<EventId>(
to_pdu_event::<&EventId>(
"END",
charlie(),
EventType::RoomMessage,
@ -522,12 +530,12 @@ pub fn INITIAL_EVENTS() -> HashMap<EventId, Arc<StateEvent>> {
),
]
.into_iter()
.map(|ev| (ev.event_id().clone(), ev))
.map(|ev| (ev.event_id().to_owned(), ev))
.collect()
}
#[allow(non_snake_case)]
pub fn INITIAL_EDGES() -> Vec<EventId> {
pub fn INITIAL_EDGES() -> Vec<Box<EventId>> {
vec!["START", "IMC", "IMB", "IJR", "IPOWER", "IMA", "CREATE"]
.into_iter()
.map(event_id)
@ -603,8 +611,8 @@ pub mod event {
fn prev_events(&self) -> Box<dyn DoubleEndedIterator<Item = &EventId> + '_> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter()),
Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| &**id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter().map(|id| &**id)),
#[allow(unreachable_patterns)]
_ => unreachable!("new PDU version"),
}
@ -612,8 +620,8 @@ pub mod event {
fn auth_events(&self) -> Box<dyn DoubleEndedIterator<Item = &EventId> + '_> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter()),
Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| &**id)),
Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter().map(|id| &**id)),
#[allow(unreachable_patterns)]
_ => unreachable!("new PDU version"),
}
@ -621,8 +629,8 @@ pub mod event {
fn redacts(&self) -> Option<&EventId> {
match &self.rest {
Pdu::RoomV1Pdu(ev) => ev.redacts.as_ref(),
Pdu::RoomV3Pdu(ev) => ev.redacts.as_ref(),
Pdu::RoomV1Pdu(ev) => ev.redacts.as_deref(),
Pdu::RoomV3Pdu(ev) => ev.redacts.as_deref(),
#[allow(unreachable_patterns)]
_ => unreachable!("new PDU version"),
}
@ -632,7 +640,7 @@ pub mod event {
#[derive(Clone, Debug, Deserialize, Serialize)]
#[allow(clippy::exhaustive_structs)]
pub struct StateEvent {
pub event_id: EventId,
pub event_id: Box<EventId>,
#[serde(flatten)]
pub rest: Pdu,
}