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: { response: {
/// A unique identifier for the event. /// A unique identifier for the event.
pub event_id: EventId, pub event_id: Box<EventId>,
} }
error: crate::Error error: crate::Error
@ -80,7 +80,7 @@ impl<'a> Request<'a> {
impl Response { impl Response {
/// Creates a new `Response` with the given event id. /// 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 } Self { event_id }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -81,7 +81,7 @@ mod tests {
#[test] #[test]
fn serialization() { 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 device: Box<DeviceId> = "123".into();
let json_data = json!({ let json_data = json!({

View File

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

View File

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

View File

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

View File

@ -32,7 +32,7 @@ mod tests {
#[test] #[test]
fn serialization() { fn serialization() {
let room_event = PolicyRuleRoomEvent { 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"), sender: user_id!("@example:example.org"),
origin_server_ts: MilliSecondsSinceUnixEpoch(1_432_735_824_653_u64.try_into().unwrap()), origin_server_ts: MilliSecondsSinceUnixEpoch(1_432_735_824_653_u64.try_into().unwrap()),
room_id: room_id!("!jEsUZKDJdhlrceRyVU:example.org"), 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")] #[serde(tag = "rel_type", rename = "m.annotation")]
pub struct Relation { pub struct Relation {
/// The event that is being reacted to. /// The event that is being reacted to.
pub event_id: EventId, pub event_id: Box<EventId>,
/// A string that holds the emoji reaction. /// A string that holds the emoji reaction.
#[serde(rename = "key")] #[serde(rename = "key")]
@ -46,7 +46,7 @@ pub struct Relation {
impl Relation { impl Relation {
/// Creates a new `Relation` with the given event ID and emoji. /// 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 } Self { event_id, emoji }
} }
} }

View File

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

View File

@ -51,7 +51,7 @@ mod tests {
alias: Some(room_alias_id!("#somewhere:localhost")), alias: Some(room_alias_id!("#somewhere:localhost")),
alt_aliases: Vec::new(), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None, prev_content: None,
room_id: room_id!("!dummy:example.com"), room_id: room_id!("!dummy:example.com"),

View File

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

View File

@ -119,7 +119,7 @@ pub enum Relation {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Replacement { pub struct Replacement {
/// The ID of the event being replacing. /// The ID of the event being replacing.
pub event_id: EventId, pub event_id: Box<EventId>,
} }
/// A reference to another event. /// A reference to another event.
@ -128,13 +128,13 @@ pub struct Replacement {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Reference { pub struct Reference {
/// The event we are referencing. /// The event we are referencing.
pub event_id: EventId, pub event_id: Box<EventId>,
} }
#[cfg(feature = "unstable-pre-spec")] #[cfg(feature = "unstable-pre-spec")]
impl Reference { impl Reference {
/// Creates a new `Reference` with the given event ID. /// 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 } Self { event_id }
} }
} }
@ -145,7 +145,7 @@ impl Reference {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Annotation { pub struct Annotation {
/// The event that is being annotated. /// The event that is being annotated.
pub event_id: EventId, pub event_id: Box<EventId>,
/// The annotation. /// The annotation.
pub key: String, pub key: String,
@ -154,7 +154,7 @@ pub struct Annotation {
#[cfg(feature = "unstable-pre-spec")] #[cfg(feature = "unstable-pre-spec")]
impl Annotation { impl Annotation {
/// Creates a new `Annotation` with the given event ID and key. /// 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 } Self { event_id, key }
} }
} }
@ -298,7 +298,7 @@ mod tests {
session_id: "session_id".into(), session_id: "session_id".into(),
}), }),
relates_to: Some(Relation::Reply { 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 { Self {
relates_to: Some(Relation::Reply { 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) ..Self::text_plain(body)
} }
@ -134,7 +134,7 @@ impl RoomMessageEventContent {
let body = format!("{}\n\n{}", quoted, reply); let body = format!("{}\n\n{}", quoted, reply);
Self { Self {
relates_to: Some(Relation::Reply { 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) ..Self::notice_plain(body)
} }
@ -361,12 +361,12 @@ pub enum Relation {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct InReplyTo { pub struct InReplyTo {
/// The event being replied to. /// The event being replied to.
pub event_id: EventId, pub event_id: Box<EventId>,
} }
impl InReplyTo { impl InReplyTo {
/// Creates a new `InReplyTo` with the given event ID. /// 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 } Self { event_id }
} }
} }
@ -377,7 +377,7 @@ impl InReplyTo {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Replacement { pub struct Replacement {
/// The ID of the event being replacing. /// The ID of the event being replacing.
pub event_id: EventId, pub event_id: Box<EventId>,
/// New content. /// New content.
pub new_content: Box<RoomMessageEventContent>, pub new_content: Box<RoomMessageEventContent>,
@ -386,7 +386,7 @@ pub struct Replacement {
#[cfg(feature = "unstable-pre-spec")] #[cfg(feature = "unstable-pre-spec")]
impl Replacement { impl Replacement {
/// Creates a new `Replacement` with the given event ID and new content. /// 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 } Self { event_id, new_content }
} }
} }

View File

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

View File

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

View File

@ -41,7 +41,7 @@ mod tests {
fn serialization_with_optional_fields_as_none() { fn serialization_with_optional_fields_as_none() {
let name_event = StateEvent { let name_event = StateEvent {
content: RoomNameEventContent { name: "The room name".try_into().ok() }, 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None, prev_content: None,
room_id: room_id!("!n8f893n9:example.com"), room_id: room_id!("!n8f893n9:example.com"),
@ -70,7 +70,7 @@ mod tests {
fn serialization_with_all_fields() { fn serialization_with_all_fields() {
let name_event = StateEvent { let name_event = StateEvent {
content: RoomNameEventContent { name: "The room name".try_into().ok() }, 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomNameEventContent { name: "The old name".try_into().ok() }), prev_content: Some(RoomNameEventContent { name: "The old name".try_into().ok() }),
room_id: room_id!("!n8f893n9:example.com"), 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)] #[ruma_event(type = "m.room.pinned_events", kind = State)]
pub struct RoomPinnedEventsEventContent { pub struct RoomPinnedEventsEventContent {
/// An ordered list of event IDs to pin. /// An ordered list of event IDs to pin.
pub pinned: Vec<EventId>, pub pinned: Vec<Box<EventId>>,
} }
impl RoomPinnedEventsEventContent { impl RoomPinnedEventsEventContent {
/// Creates a new `RoomPinnedEventsEventContent` with the given events. /// 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 } Self { pinned }
} }
} }

View File

@ -179,7 +179,7 @@ mod tests {
users_default: int!(0), users_default: int!(0),
notifications: NotificationPowerLevels::default(), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None, prev_content: None,
room_id: room_id!("!n8f893n9:example.com"), room_id: room_id!("!n8f893n9:example.com"),
@ -222,7 +222,7 @@ mod tests {
users_default: int!(23), users_default: int!(23),
notifications: assign!(NotificationPowerLevels::new(), { room: 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomPowerLevelsEventContent { prev_content: Some(RoomPowerLevelsEventContent {
// Make just one field different so we at least know they're two different objects. // 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, pub content: RoomRedactionEventContent,
/// The ID of the event that was redacted. /// 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. /// 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. /// The fully-qualified ID of the user who sent this event.
pub sender: UserId, pub sender: UserId,
@ -62,10 +62,10 @@ pub struct RedactedRoomRedactionEvent {
pub content: RedactedRoomRedactionEventContent, pub content: RedactedRoomRedactionEventContent,
/// The ID of the event that was redacted. /// 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. /// 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. /// The fully-qualified ID of the user who sent this event.
pub sender: UserId, pub sender: UserId,
@ -88,10 +88,10 @@ pub struct SyncRoomRedactionEvent {
pub content: RoomRedactionEventContent, pub content: RoomRedactionEventContent,
/// The ID of the event that was redacted. /// 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. /// 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. /// The fully-qualified ID of the user who sent this event.
pub sender: UserId, pub sender: UserId,
@ -131,10 +131,10 @@ pub struct RedactedSyncRoomRedactionEvent {
pub content: RedactedRoomRedactionEventContent, pub content: RedactedRoomRedactionEventContent,
/// The ID of the event that was redacted. /// 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. /// 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. /// The fully-qualified ID of the user who sent this event.
pub sender: UserId, pub sender: UserId,

View File

@ -50,7 +50,7 @@ fn serialize_custom_message_event() {
}, },
event_type: "m.room.message".into(), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
room_id: room_id!("!room:room.com"), room_id: room_id!("!room:room.com"),
sender: user_id!("@carl:example.com"), sender: user_id!("@carl:example.com"),
@ -90,7 +90,7 @@ fn serialize_custom_state_event() {
}, },
event_type: "m.made.up".into(), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
prev_content: None, prev_content: None,
room_id: room_id!("!roomid:room.com"), room_id: room_id!("!roomid:room.com"),

View File

@ -202,7 +202,7 @@ fn message_room_event_deserialization() {
fn message_event_serialization() { fn message_event_serialization() {
let event = MessageEvent { let event = MessageEvent {
content: RoomMessageEventContent::text_plain("test"), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(0)),
room_id: room_id!("!roomid:example.com"), room_id: room_id!("!roomid:example.com"),
sender: user_id!("@test:example.com"), sender: user_id!("@test:example.com"),
@ -285,7 +285,7 @@ fn alias_event_field_access() {
Ok(AnyRoomEvent::State(state_event)) Ok(AnyRoomEvent::State(state_event))
if state_event.state_key() == "" if state_event.state_key() == ""
&& state_event.room_id() == &room_id!("!room:room.com") && 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") && state_event.sender() == &user_id!("@example:localhost")
); );

View File

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

View File

@ -86,7 +86,7 @@ fn serialize_message_event() {
}), }),
mxc_uri!("mxc://matrix.org/arsrns98rsRSR"), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
room_id: room_id!("!roomid:room.com"), room_id: room_id!("!roomid:room.com"),
sender: user_id!("@carl:example.com"), sender: user_id!("@carl:example.com"),

View File

@ -32,7 +32,7 @@ fn message_serialize_sticker() {
}), }),
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs"), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
room_id: room_id!("!roomid:room.com"), room_id: room_id!("!roomid:room.com"),
sender: user_id!("@carl:example.com"), sender: user_id!("@carl:example.com"),

View File

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

View File

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

View File

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

View File

@ -40,7 +40,7 @@ fn serialization() {
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd"), mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd"),
None, None,
))), ))),
event_id: event_id!("$143273582443PhrSn:example.org"), event_id: event_id!("$143273582443PhrSn:example.org").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10_000)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10_000)),
room_id: room_id!("!testroomid:example.org"), room_id: room_id!("!testroomid:example.org"),
sender: user_id!("@user:example.org"), sender: user_id!("@user:example.org"),
@ -203,7 +203,9 @@ fn relates_to_content_serialization() {
let message_event_content = let message_event_content =
assign!(RoomMessageEventContent::text_plain("> <@test:example.com> test\n\ntest reply"), { assign!(RoomMessageEventContent::text_plain("> <@test:example.com> test\n\ntest reply"), {
relates_to: Some(Relation::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() { fn serialize_aliases_with_prev_content() {
let aliases_event = StateEvent { let aliases_event = StateEvent {
content: RoomAliasesEventContent::new(vec![room_alias_id!("#somewhere:localhost")]), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: Some(RoomAliasesEventContent::new(vec![room_alias_id!("#inner:localhost")])), prev_content: Some(RoomAliasesEventContent::new(vec![room_alias_id!("#inner:localhost")])),
room_id: room_id!("!roomid:room.com"), room_id: room_id!("!roomid:room.com"),
@ -56,7 +56,7 @@ fn serialize_aliases_with_prev_content() {
fn serialize_aliases_without_prev_content() { fn serialize_aliases_without_prev_content() {
let aliases_event = StateEvent { let aliases_event = StateEvent {
content: RoomAliasesEventContent::new(vec![room_alias_id!("#somewhere:localhost")]), 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)), origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
prev_content: None, prev_content: None,
room_id: room_id!("!roomid:room.com"), room_id: room_id!("!roomid:room.com"),

View File

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

View File

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

View File

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

View File

@ -26,10 +26,10 @@ ruma_api! {
response: { response: {
/// The full set of authorization events that make up the state of the /// The full set of authorization events that make up the state of the
/// room, and their authorization events, recursively. /// 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. /// 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 { impl Response {
/// Creates a new `Response` with the given auth chain IDs and room state IDs. /// 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 } Self { auth_chain_ids, pdu_ids }
} }
} }

View File

@ -14,7 +14,7 @@ struct WrappedError {
} }
pub fn serialize<S>( pub fn serialize<S>(
response: &BTreeMap<EventId, Result<(), String>>, response: &BTreeMap<Box<EventId>, Result<(), String>>,
serializer: S, serializer: S,
) -> Result<S::Ok, S::Error> ) -> Result<S::Ok, S::Error>
where where
@ -33,16 +33,17 @@ where
map.end() map.end()
} }
#[allow(clippy::type_complexity)]
pub fn deserialize<'de, D>( pub fn deserialize<'de, D>(
deserializer: D, deserializer: D,
) -> Result<BTreeMap<EventId, Result<(), String>>, D::Error> ) -> Result<BTreeMap<Box<EventId>, Result<(), String>>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
struct PduProcessResponseVisitor; struct PduProcessResponseVisitor;
impl<'de> Visitor<'de> for 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 { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("A map of EventIds to a map of optional errors") formatter.write_str("A map of EventIds to a map of optional errors")
@ -54,7 +55,7 @@ where
{ {
let mut map = BTreeMap::new(); 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 { let v = match value.error {
None => Ok(()), None => Ok(()),
Some(error) => Err(error), Some(error) => Err(error),
@ -79,8 +80,11 @@ mod tests {
#[test] #[test]
fn serialize_error() { fn serialize_error() {
let mut response: BTreeMap<EventId, Result<(), String>> = BTreeMap::new(); let mut response: BTreeMap<Box<EventId>, Result<(), String>> = BTreeMap::new();
response.insert(event_id!("$someevent:matrix.org"), Err("Some processing error.".into())); response.insert(
event_id!("$someevent:matrix.org").to_owned(),
Err("Some processing error.".into()),
);
let serialized = serialize(&response, JsonSerializer).unwrap(); let serialized = serialize(&response, JsonSerializer).unwrap();
let json = json!({ let json = json!({
@ -91,8 +95,8 @@ mod tests {
#[test] #[test]
fn serialize_ok() { fn serialize_ok() {
let mut response: BTreeMap<EventId, Result<(), String>> = BTreeMap::new(); let mut response: BTreeMap<Box<EventId>, Result<(), String>> = BTreeMap::new();
response.insert(event_id!("$someevent:matrix.org"), Ok(())); response.insert(event_id!("$someevent:matrix.org").to_owned(), Ok(()));
let serialized = serialize(&response, serde_json::value::Serializer).unwrap(); let serialized = serialize(&response, serde_json::value::Serializer).unwrap();
let json = json!({ let json = json!({
@ -110,7 +114,7 @@ mod tests {
let response = deserialize(json).unwrap(); let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org"); 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."); assert_eq!(event_response, "Some processing error.");
} }
@ -123,7 +127,7 @@ mod tests {
let response = deserialize(json).unwrap(); let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org"); 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] #[test]
@ -135,7 +139,7 @@ mod tests {
let response = deserialize(json).unwrap(); let response = deserialize(json).unwrap();
let event_id = event_id!("$someevent:matrix.org"); 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, ""); assert_eq!(event_response, "");
} }
@ -145,6 +149,6 @@ mod tests {
"$someevent:matrix.org": {} "$someevent:matrix.org": {}
}); });
let response = deserialize(json).unwrap(); 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, pub data: Receipt,
/// The extremity event ID the user has read up to. /// The extremity event ID the user has read up to.
pub event_ids: Vec<EventId>, pub event_ids: Vec<Box<EventId>>,
} }
impl ReceiptData { impl ReceiptData {
/// Creates a new `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 } Self { data, event_ids }
} }
} }

View File

@ -49,7 +49,7 @@ ruma_api! {
response: { response: {
/// Map of event IDs and response for each PDU given in the request. /// Map of event IDs and response for each PDU given in the request.
#[serde(with = "crate::serde::pdu_process_response")] #[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 { impl Response {
/// Creates a new `Response` with the given PDUs. /// 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 } 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"); assert!(event_id::validate(&id.value()).is_ok(), "Invalid event id");
let output = quote! { 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() 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(':') {
pub fn validate(s: &str) -> Result<Option<NonZeroU8>, Error> { validate_delimited_id(s, &['$'])?;
Ok(match s.contains(':') { } else if !s.starts_with('$') {
true => Some(parse_id(s, &['$'])?),
false => {
if !s.starts_with('$') {
return Err(Error::MissingLeadingSigil); 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..])?; server_name::validate(&id[colon_idx + 1..])?;
Ok(NonZeroU8::new(colon_idx as u8).unwrap()) 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. //! Matrix event identifiers.
use std::{convert::TryFrom, fmt, num::NonZeroU8}; use std::convert::TryInto;
use ruma_identifiers_validation::event_id::validate;
use crate::ServerName; use crate::ServerName;
opaque_identifier_validated! {
/// A Matrix event ID. /// A Matrix event ID.
/// ///
/// An `EventId` is generated randomly or converted from a string slice, and can be converted back /// An `EventId` is generated randomly or converted from a string slice, and can be converted
/// into a string as needed. /// back into a string as needed.
/// ///
/// # Room versions /// # Room versions
/// ///
/// Matrix specifies multiple [room versions](https://matrix.org/docs/spec/#room-versions) and the /// Matrix specifies multiple [room versions](https://matrix.org/docs/spec/#room-versions) and
/// format of event identifiers differ between them. The original format used by room versions 1 /// the format of event identifiers differ between them. The original format used by room
/// and 2 uses a short pseudorandom "localpart" followed by the hostname and port of the /// versions 1 and 2 uses a short pseudorandom "localpart" followed by the hostname and port of
/// originating homeserver. Later room versions change event identifiers to be a hash of the event /// the originating homeserver. Later room versions change event identifiers to be a hash of the
/// encoded with Base64. Some of the methods provided by `EventId` are only relevant to the /// event encoded with Base64. Some of the methods provided by `EventId` are only relevant to
/// original event format. /// the original event format.
/// ///
/// ``` /// ```
/// # use std::convert::TryFrom; /// # use std::convert::TryFrom;
/// # use ruma_identifiers::EventId; /// # use ruma_identifiers::EventId;
/// // Original format /// // Original format
/// assert_eq!( /// assert_eq!(
/// EventId::try_from("$h29iv0s8:example.com").unwrap().as_ref(), /// <&EventId>::try_from("$h29iv0s8:example.com").unwrap(),
/// "$h29iv0s8:example.com" /// "$h29iv0s8:example.com"
/// ); /// );
/// // Room version 3 format /// // Room version 3 format
/// assert_eq!( /// assert_eq!(
/// EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap().as_ref(), /// <&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap(),
/// "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk" /// "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
/// ); /// );
/// // Room version 4 format /// // Room version 4 format
/// assert_eq!( /// assert_eq!(
/// EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap().as_ref(), /// <&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap(),
/// "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg" /// "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
/// ); /// );
/// ``` /// ```
#[derive(Clone)] pub type EventId [ validate ];
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)
}
} }
impl EventId { 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 /// This should only be used for events in the original format as used by Matrix room versions
/// 1 and 2. /// 1 and 2.
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new(server_name: &ServerName) -> Self { pub fn new(server_name: &ServerName) -> Box<Self> {
use crate::generate_localpart; Self::from_owned(format!("${}:{}", crate::generate_localpart(18), server_name).into())
let full_id = format!("${}:{}", generate_localpart(18), server_name).into();
Self { full_id, colon_idx: NonZeroU8::new(19) }
} }
/// Returns the event's unique ID. /// Returns the event's unique ID.
@ -70,36 +60,21 @@ impl EventId {
/// "localpart" that precedes the homeserver. For later formats, this is the entire ID without /// "localpart" that precedes the homeserver. For later formats, this is the entire ID without
/// the leading `$` sigil. /// the leading `$` sigil.
pub fn localpart(&self) -> &str { pub fn localpart(&self) -> &str {
let idx = match self.colon_idx { let idx = self.colon_idx().unwrap_or_else(|| self.as_str().len());
Some(idx) => idx.get() as usize, &self.as_str()[1..idx]
None => self.full_id.len(),
};
&self.full_id[1..idx]
} }
/// Returns the server name of the event ID. /// 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. /// Only applicable to events in the original format as used by Matrix room versions 1 and 2.
pub fn server_name(&self) -> Option<&ServerName> { pub fn server_name(&self) -> Option<&ServerName> {
self.colon_idx self.colon_idx().map(|idx| self.as_str()[idx as usize + 1..].try_into().unwrap())
.map(|idx| <&ServerName>::try_from(&self.full_id[idx.get() as usize + 1..]).unwrap())
}
} }
/// Attempts to create a new Matrix event ID from a string representation. fn colon_idx(&self) -> Option<usize> {
/// self.as_str().find(':')
/// 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)] #[cfg(test)]
mod tests { mod tests {
@ -111,9 +86,7 @@ mod tests {
#[test] #[test]
fn valid_original_event_id() { fn valid_original_event_id() {
assert_eq!( assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com") <&EventId>::try_from("$39hvsi03hlne:example.com").expect("Failed to create EventId."),
.expect("Failed to create EventId.")
.as_ref(),
"$39hvsi03hlne:example.com" "$39hvsi03hlne:example.com"
); );
} }
@ -121,9 +94,8 @@ mod tests {
#[test] #[test]
fn valid_base64_event_id() { fn valid_base64_event_id() {
assert_eq!( assert_eq!(
EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk") <&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.") .expect("Failed to create EventId."),
.as_ref(),
"$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk" "$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk"
) )
} }
@ -131,9 +103,8 @@ mod tests {
#[test] #[test]
fn valid_url_safe_base64_event_id() { fn valid_url_safe_base64_event_id() {
assert_eq!( assert_eq!(
EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg") <&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId.") .expect("Failed to create EventId."),
.as_ref(),
"$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg" "$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg"
) )
} }
@ -155,7 +126,8 @@ mod tests {
fn serialize_valid_original_event_id() { fn serialize_valid_original_event_id() {
assert_eq!( assert_eq!(
serde_json::to_string( 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."), .expect("Failed to convert EventId to JSON."),
r#""$39hvsi03hlne:example.com""# r#""$39hvsi03hlne:example.com""#
@ -167,7 +139,7 @@ mod tests {
fn serialize_valid_base64_event_id() { fn serialize_valid_base64_event_id() {
assert_eq!( assert_eq!(
serde_json::to_string( serde_json::to_string(
&EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk") <&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.") .expect("Failed to create EventId.")
) )
.expect("Failed to convert EventId to JSON."), .expect("Failed to convert EventId to JSON."),
@ -180,7 +152,7 @@ mod tests {
fn serialize_valid_url_safe_base64_event_id() { fn serialize_valid_url_safe_base64_event_id() {
assert_eq!( assert_eq!(
serde_json::to_string( 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 create EventId.")
) )
.expect("Failed to convert EventId to JSON."), .expect("Failed to convert EventId to JSON."),
@ -192,9 +164,9 @@ mod tests {
#[test] #[test]
fn deserialize_valid_original_event_id() { fn deserialize_valid_original_event_id() {
assert_eq!( 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"), .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] #[test]
fn deserialize_valid_base64_event_id() { fn deserialize_valid_base64_event_id() {
assert_eq!( assert_eq!(
serde_json::from_str::<EventId>(r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#) serde_json::from_str::<Box<EventId>>(
r#""$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk""#
)
.expect("Failed to convert JSON to EventId"), .expect("Failed to convert JSON to EventId"),
EventId::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk") <&EventId>::try_from("$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk")
.expect("Failed to create EventId.") .expect("Failed to create EventId.")
); );
} }
@ -213,9 +187,11 @@ mod tests {
#[test] #[test]
fn deserialize_valid_url_safe_base64_event_id() { fn deserialize_valid_url_safe_base64_event_id() {
assert_eq!( assert_eq!(
serde_json::from_str::<EventId>(r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#) serde_json::from_str::<Box<EventId>>(
r#""$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg""#
)
.expect("Failed to convert JSON to EventId"), .expect("Failed to convert JSON to EventId"),
EventId::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg") <&EventId>::try_from("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg")
.expect("Failed to create EventId.") .expect("Failed to create EventId.")
); );
} }
@ -223,9 +199,8 @@ mod tests {
#[test] #[test]
fn valid_original_event_id_with_explicit_standard_port() { fn valid_original_event_id_with_explicit_standard_port() {
assert_eq!( assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:443") <&EventId>::try_from("$39hvsi03hlne:example.com:443")
.expect("Failed to create EventId.") .expect("Failed to create EventId."),
.as_ref(),
"$39hvsi03hlne:example.com:443" "$39hvsi03hlne:example.com:443"
); );
} }
@ -233,9 +208,8 @@ mod tests {
#[test] #[test]
fn valid_original_event_id_with_non_standard_port() { fn valid_original_event_id_with_non_standard_port() {
assert_eq!( assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:5000") <&EventId>::try_from("$39hvsi03hlne:example.com:5000")
.expect("Failed to create EventId.") .expect("Failed to create EventId."),
.as_ref(),
"$39hvsi03hlne:example.com:5000" "$39hvsi03hlne:example.com:5000"
); );
} }
@ -243,7 +217,7 @@ mod tests {
#[test] #[test]
fn missing_original_event_id_sigil() { fn missing_original_event_id_sigil() {
assert_eq!( assert_eq!(
EventId::try_from("39hvsi03hlne:example.com").unwrap_err(), <&EventId>::try_from("39hvsi03hlne:example.com").unwrap_err(),
Error::MissingLeadingSigil Error::MissingLeadingSigil
); );
} }
@ -251,7 +225,7 @@ mod tests {
#[test] #[test]
fn missing_base64_event_id_sigil() { fn missing_base64_event_id_sigil() {
assert_eq!( assert_eq!(
EventId::try_from("acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap_err(), <&EventId>::try_from("acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk").unwrap_err(),
Error::MissingLeadingSigil Error::MissingLeadingSigil
); );
} }
@ -259,20 +233,20 @@ mod tests {
#[test] #[test]
fn missing_url_safe_base64_event_id_sigil() { fn missing_url_safe_base64_event_id_sigil() {
assert_eq!( assert_eq!(
EventId::try_from("Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap_err(), <&EventId>::try_from("Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg").unwrap_err(),
Error::MissingLeadingSigil Error::MissingLeadingSigil
); );
} }
#[test] #[test]
fn invalid_event_id_host() { 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] #[test]
fn invalid_event_id_port() { fn invalid_event_id_port() {
assert_eq!( assert_eq!(
EventId::try_from("$39hvsi03hlne:example.com:notaport").unwrap_err(), <&EventId>::try_from("$39hvsi03hlne:example.com:notaport").unwrap_err(),
Error::InvalidServerName Error::InvalidServerName
); );
} }

View File

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

View File

@ -261,6 +261,8 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
Some(parse_quote! { ::std::string::String }) Some(parse_quote! { ::std::string::String })
} else if last_seg.ident == "ClientSecret" } else if last_seg.ident == "ClientSecret"
|| last_seg.ident == "DeviceId" || last_seg.ident == "DeviceId"
|| last_seg.ident == "DeviceKeyId"
|| last_seg.ident == "EventId"
|| last_seg.ident == "ServerName" || last_seg.ident == "ServerName"
|| last_seg.ident == "SessionId" || last_seg.ident == "SessionId"
|| last_seg.ident == "RawJsonValue" || 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 /// For when an event ID, coupled with a specific room version, doesn't have a server name
/// embedded. /// embedded.
#[error("Event Id {0:?} should have a server name for the given room version {1:?}")] #[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 /// 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. /// public key derived from it's private key.
@ -229,7 +229,7 @@ impl ParseError {
event_id: &EventId, event_id: &EventId,
room_version: &RoomVersionId, room_version: &RoomVersionId,
) -> Error { ) -> 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>>>( 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 { match version {
RoomVersionId::Version1 | RoomVersionId::Version2 => match object.get("event_id") { RoomVersionId::Version1 | RoomVersionId::Version2 => match object.get("event_id") {
Some(CanonicalJsonValue::String(raw_event_id)) => { Some(CanonicalJsonValue::String(raw_event_id)) => {
let event_id = EventId::from_str(raw_event_id) let event_id: Box<EventId> =
.map_err(|e| Error::from(ParseError::EventId(e)))?; raw_event_id.parse().map_err(|e| Error::from(ParseError::EventId(e)))?;
let server_name = event_id let server_name = event_id
.server_name() .server_name()

View File

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

View File

@ -31,7 +31,7 @@ pub use state_event::Event;
pub type StateMap<T> = HashMap<(EventType, String), T>; pub type StateMap<T> = HashMap<(EventType, String), T>;
/// A mapping of `EventId` to `T`, usually a `ServerPdu`. /// 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. /// 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>( pub fn resolve<'a, E, SSI>(
room_version: &RoomVersionId, room_version: &RoomVersionId,
state_sets: impl IntoIterator<IntoIter = SSI>, 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>, fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<StateMap<EventId>> ) -> Result<StateMap<Box<EventId>>>
where where
E: Event + Clone, E: Event + Clone,
SSI: Iterator<Item = &'a StateMap<EventId>> + Clone, SSI: Iterator<Item = &'a StateMap<Box<EventId>>> + Clone,
{ {
info!("State resolution starting"); info!("State resolution starting");
@ -124,7 +124,7 @@ where
// auth // auth
let events_to_resolve = all_conflicted let events_to_resolve = all_conflicted
.iter() .iter()
.filter(|id| !deduped_power_ev.contains(id)) .filter(|&id| !deduped_power_ev.contains(id))
.cloned() .cloned()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -136,7 +136,8 @@ where
debug!("power event: {:?}", power_event); 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); 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 /// 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. /// of the other have this is a conflicting event.
fn separate<'a>( fn separate<'a>(
state_sets_iter: impl Iterator<Item = &'a StateMap<EventId>> + Clone, state_sets_iter: impl Iterator<Item = &'a StateMap<Box<EventId>>> + Clone,
) -> (StateMap<EventId>, StateMap<Vec<EventId>>) { ) -> (StateMap<Box<EventId>>, StateMap<Vec<Box<EventId>>>) {
let mut unconflicted_state = StateMap::new(); let mut unconflicted_state = StateMap::new();
let mut conflicted_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. /// 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 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() { for id in auth_chain_sets.into_iter().flatten() {
*id_counts.entry(id).or_default() += 1; *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 /// The power level is negative because a higher power level is equated to an earlier (further back
/// in time) origin server timestamp. /// in time) origin server timestamp.
fn reverse_topological_power_sort<E: Event>( fn reverse_topological_power_sort<E: Event>(
events_to_sort: Vec<EventId>, events_to_sort: Vec<Box<EventId>>,
auth_diff: &HashSet<EventId>, auth_diff: &HashSet<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>, fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<Vec<EventId>> { ) -> Result<Vec<Box<EventId>>> {
debug!("reverse topological sort of power events"); debug!("reverse topological sort of power events");
let mut graph = HashMap::new(); 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, // This return value is the key used for sorting events,
// events are then sorted by power level, time, // events are then sorted by power level, time,
// and lexically by event_id. // 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 /// `key_fn` is used as a tie breaker. The tie breaker happens based on power level, age, and
/// event_id. /// event_id.
pub fn lexicographical_topological_sort<F>( pub fn lexicographical_topological_sort<F>(
graph: &HashMap<EventId, HashSet<EventId>>, graph: &HashMap<Box<EventId>, HashSet<Box<EventId>>>,
key_fn: F, key_fn: F,
) -> Result<Vec<EventId>> ) -> Result<Vec<Box<EventId>>>
where where
F: Fn(&EventId) -> Result<(Int, MilliSecondsSinceUnixEpoch, EventId)>, F: Fn(&EventId) -> Result<(Int, MilliSecondsSinceUnixEpoch, Box<EventId>)>,
{ {
info!("starting lexicographical topological sort"); info!("starting lexicographical topological sort");
// NOTE: an event that has no incoming edges happened most recently, // 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) // 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 // 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. // Vec of nodes that have zero out degree, least recent events.
let mut zero_outdegree = vec![]; let mut zero_outdegree = vec![];
@ -295,8 +298,7 @@ where
let mut sorted = vec![]; let mut sorted = vec![];
// Destructure the `Reverse` and take the smallest `node` each time // Destructure the `Reverse` and take the smallest `node` each time
while let Some(Reverse((_, node))) = heap.pop() { 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 // The number of outgoing edges this node has
let out = outdegree_map let out = outdegree_map
.get_mut(parent) .get_mut(parent)
@ -310,7 +312,7 @@ where
} }
// synapse yields we push then return the vec // synapse yields we push then return the vec
sorted.push(node.clone()); sorted.push(node.to_owned());
} }
Ok(sorted) Ok(sorted)
@ -373,16 +375,16 @@ fn get_power_level_for_sender<E: Event>(
/// ## Returns /// ## Returns
/// ///
/// The `unconflicted_state` combined with the newly auth'ed events. So any event that fails the /// 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 /// 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. /// `fetch_event` closure and verify each event using the `event_auth::auth_check` function.
fn iterative_auth_check<E: Event + Clone>( fn iterative_auth_check<E: Event + Clone>(
room_version: &RoomVersion, room_version: &RoomVersion,
events_to_check: &[EventId], events_to_check: &[Box<EventId>],
unconflicted_state: StateMap<EventId>, unconflicted_state: StateMap<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>, fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<StateMap<EventId>> { ) -> Result<StateMap<Box<EventId>>> {
info!("starting iterative auth check"); info!("starting iterative auth check");
debug!("performing auth checks on {:?}", events_to_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 /// the events before (with the first power level as a parent) will be marked as depth 1. depth 1 is
/// "older" than depth 0. /// "older" than depth 0.
fn mainline_sort<E: Event>( fn mainline_sort<E: Event>(
to_sort: &[EventId], to_sort: &[Box<EventId>],
resolved_power_level: Option<&EventId>, resolved_power_level: Option<&EventId>,
fetch_event: impl Fn(&EventId) -> Option<E>, fetch_event: impl Fn(&EventId) -> Option<E>,
) -> Result<Vec<EventId>> { ) -> Result<Vec<Box<EventId>>> {
debug!("mainline sort of events"); debug!("mainline sort of events");
// There are no EventId's to sort, bail. // There are no EventId's to sort, bail.
@ -488,7 +490,7 @@ fn mainline_sort<E: Event>(
} }
let mut mainline = vec![]; 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 { while let Some(p) = pl {
mainline.push(p.clone()); mainline.push(p.clone());
@ -499,7 +501,7 @@ fn mainline_sort<E: Event>(
let ev = fetch_event(aid) let ev = fetch_event(aid)
.ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?; .ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?;
if is_type_and_key(&ev, &EventType::RoomPowerLevels, "") { if is_type_and_key(&ev, &EventType::RoomPowerLevels, "") {
pl = Some(aid.clone()); pl = Some(aid.to_owned());
break; break;
} }
} }
@ -548,7 +550,7 @@ fn get_mainline_depth<E: Event>(
) -> Result<usize> { ) -> Result<usize> {
while let Some(sort_ev) = event { while let Some(sort_ev) = event {
debug!("mainline event_id {}", sort_ev.event_id()); 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) { if let Some(depth) = mainline_map.get(id) {
return Ok(*depth); return Ok(*depth);
} }
@ -568,9 +570,9 @@ fn get_mainline_depth<E: Event>(
} }
fn add_event_and_auth_chain_to_graph<E: Event>( fn add_event_and_auth_chain_to_graph<E: Event>(
graph: &mut HashMap<EventId, HashSet<EventId>>, graph: &mut HashMap<Box<EventId>, HashSet<Box<EventId>>>,
event_id: EventId, event_id: Box<EventId>,
auth_diff: &HashSet<EventId>, auth_diff: &HashSet<Box<EventId>>,
fetch_event: impl Fn(&EventId) -> Option<E>, fetch_event: impl Fn(&EventId) -> Option<E>,
) { ) {
let mut state = vec![event_id]; 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() { for aid in fetch_event(&eid).as_ref().map(|ev| ev.auth_events()).into_iter().flatten() {
if auth_diff.contains(aid) { if auth_diff.contains(aid) {
if !graph.contains_key(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 // 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,7 +692,9 @@ mod tests {
let power_level = resolved_power.get(&(EventType::RoomPowerLevels, "".to_owned())); let power_level = resolved_power.get(&(EventType::RoomPowerLevels, "".to_owned()));
let sorted_event_ids = let sorted_event_ids =
crate::mainline_sort(&events_to_sort, power_level, |id| events.get(id).map(Arc::clone)) crate::mainline_sort(&events_to_sort, power_level.map(|id| &**id), |id| {
events.get(id).map(Arc::clone)
})
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1066,7 +1070,7 @@ mod tests {
}; };
let res = crate::lexicographical_topological_sort(&graph, |id| { 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(); .unwrap();
@ -1193,7 +1197,7 @@ mod tests {
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn BAN_STATE_SET() -> HashMap<EventId, Arc<StateEvent>> { fn BAN_STATE_SET() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![ vec![
to_pdu_event( to_pdu_event(
"PA", "PA",
@ -1238,7 +1242,7 @@ mod tests {
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn JOIN_RULE() -> HashMap<EventId, Arc<StateEvent>> { fn JOIN_RULE() -> HashMap<Box<EventId>, Arc<StateEvent>> {
vec![ vec![
to_pdu_event( to_pdu_event(
"JR", "JR",

View File

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