Replace HashMap with BTreeMap

This commit is contained in:
Jonas Platte 2020-04-19 17:46:36 +02:00
parent 013decf401
commit 2480bb292a
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
21 changed files with 116 additions and 107 deletions

View File

@ -153,7 +153,7 @@ impl ToTokens for RumaEvent {
} }
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
fn unsigned(&self) -> &serde_json::Map<String, serde_json::Value> { fn unsigned(&self) -> &std::collections::BTreeMap<String, serde_json::Value> {
&self.unsigned &self.unsigned
} }
} }
@ -295,8 +295,8 @@ fn populate_room_event_fields(content_name: Ident, fields: Vec<Field>) -> Vec<Fi
pub sender: ruma_identifiers::UserId, pub sender: ruma_identifiers::UserId,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default, skip_serializing_if = "serde_json::Map::is_empty")] #[serde(default, skip_serializing_if = "std::collections::BTreeMap::is_empty")]
pub unsigned: serde_json::Map<String, serde_json::Value>, pub unsigned: std::collections::BTreeMap<String, serde_json::Value>,
}; };
fields.extend(punctuated_fields.into_iter().map(|p| p.field)); fields.extend(punctuated_fields.into_iter().map(|p| p.field));

View File

@ -112,7 +112,7 @@ mod parse;
/// /// /// ///
/// /// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered /// /// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered
/// /// *direct* for that particular user. /// /// *direct* for that particular user.
/// std::collections::HashMap<ruma_identifiers::UserId, Vec<ruma_identifiers::RoomId>> /// std::collections::BTreeMap<ruma_identifiers::UserId, Vec<ruma_identifiers::RoomId>>
/// } /// }
/// } /// }
/// } /// }

View File

@ -1,6 +1,6 @@
//! Types for the *m.direct* event. //! Types for the *m.direct* event.
use std::collections::HashMap; use std::collections::BTreeMap;
use ruma_events_macros::ruma_event; use ruma_events_macros::ruma_event;
use ruma_identifiers::{RoomId, UserId}; use ruma_identifiers::{RoomId, UserId};
@ -15,14 +15,14 @@ ruma_event! {
/// ///
/// A mapping of `UserId`s to a list of `RoomId`s which are considered *direct* for that /// A mapping of `UserId`s to a list of `RoomId`s which are considered *direct* for that
/// particular user. /// particular user.
HashMap<UserId, Vec<RoomId>> BTreeMap<UserId, Vec<RoomId>>
}, },
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashMap; use std::collections::BTreeMap;
use ruma_identifiers::{RoomId, UserId}; use ruma_identifiers::{RoomId, UserId};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
@ -32,7 +32,7 @@ mod tests {
#[test] #[test]
fn serialization() { fn serialization() {
let mut content: DirectEventContent = HashMap::new(); let mut content: DirectEventContent = BTreeMap::new();
let alice = UserId::new("ruma.io").unwrap(); let alice = UserId::new("ruma.io").unwrap();
let room = vec![RoomId::new("ruma.io").unwrap()]; let room = vec![RoomId::new("ruma.io").unwrap()];

View File

@ -6,7 +6,7 @@ use std::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// The type of an event. /// The type of an event.
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
// Cow<str> because deserialization sometimes needs to copy to unescape things // Cow<str> because deserialization sometimes needs to copy to unescape things
#[serde(from = "Cow<'_, str>", into = "String")] #[serde(from = "Cow<'_, str>", into = "String")]
pub enum EventType { pub enum EventType {

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, convert::Infallible, fmt::Display}; use std::{collections::BTreeMap, convert::Infallible, fmt::Display};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
@ -35,7 +35,7 @@ impl FromRaw for serde_json::Value {
} }
} }
impl<K, V, S> FromRaw for HashMap<K, V, S> impl<K, V> FromRaw for BTreeMap<K, V>
where where
Self: DeserializeOwned, Self: DeserializeOwned,
{ {

View File

@ -1,6 +1,6 @@
//! Types for the *m.key.verification.mac* event. //! Types for the *m.key.verification.mac* event.
use std::collections::HashMap; use std::collections::BTreeMap;
use ruma_events_macros::ruma_event; use ruma_events_macros::ruma_event;
@ -20,7 +20,7 @@ ruma_event! {
/// A map of the key ID to the MAC of the key, using the algorithm in the verification process. /// A map of the key ID to the MAC of the key, using the algorithm in the verification process.
/// ///
/// The MAC is encoded as unpadded Base64. /// The MAC is encoded as unpadded Base64.
pub mac: HashMap<String, String>, pub mac: BTreeMap<String, String>,
/// The MAC of the comma-separated, sorted, list of key IDs given in the `mac` property, encoded /// The MAC of the comma-separated, sorted, list of key IDs given in the `mac` property, encoded
/// as unpadded Base64. /// as unpadded Base64.

View File

@ -44,7 +44,7 @@
//! They have at least the following additional keys: //! They have at least the following additional keys:
//! * `state_key`, a string which serves as a sort of "sub-type." //! * `state_key`, a string which serves as a sort of "sub-type."
//! The state key allows a room to persist multiple state events of the same type. //! The state key allows a room to persist multiple state events of the same type.
//! You can think of a room's state events as being a `HashMap` where the keys are the tuple //! You can think of a room's state events as being a `BTreeMap` where the keys are the tuple
//! `(event_type, state_key)`. //! `(event_type, state_key)`.
//! * Optionally, `prev_content`, a JSON object containing the `content` object from the //! * Optionally, `prev_content`, a JSON object containing the `content` object from the
//! previous event of the given `(event_type, state_key)` tuple in the given room. //! previous event of the given `(event_type, state_key)` tuple in the given room.
@ -116,6 +116,7 @@
#![allow(clippy::use_self)] #![allow(clippy::use_self)]
use std::{ use std::{
collections::BTreeMap,
error::Error, error::Error,
fmt::{Debug, Display, Formatter, Result as FmtResult}, fmt::{Debug, Display, Formatter, Result as FmtResult},
time::SystemTime, time::SystemTime,
@ -127,7 +128,7 @@ use serde::{
ser::SerializeMap, ser::SerializeMap,
Deserialize, Deserializer, Serialize, Serializer, Deserialize, Deserializer, Serialize, Serializer,
}; };
use serde_json::{Map, Value}; use serde_json::Value;
pub use self::{custom::CustomEvent, custom_room::CustomRoomEvent, custom_state::CustomStateEvent}; pub use self::{custom::CustomEvent, custom_room::CustomRoomEvent, custom_state::CustomStateEvent};
@ -317,7 +318,7 @@ impl Error for FromStrError {}
/// A meaningless value that serializes to an empty JSON object. /// A meaningless value that serializes to an empty JSON object.
/// ///
/// This type is used in a few places where the Matrix specification requires an empty JSON object, /// This type is used in a few places where the Matrix specification requires an empty JSON object,
/// but it's wasteful to represent it as a `HashMap` in Rust code. /// but it's wasteful to represent it as a `BTreeMap` in Rust code.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Empty; pub struct Empty;
@ -394,7 +395,7 @@ pub trait RoomEvent: Event {
fn sender(&self) -> &UserId; fn sender(&self) -> &UserId;
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
fn unsigned(&self) -> &Map<String, Value>; fn unsigned(&self) -> &BTreeMap<String, Value>;
} }
/// An event that describes persistent state about a room. /// An event that describes persistent state about a room.
@ -459,13 +460,13 @@ mod custom {
} }
mod custom_room { mod custom_room {
use std::time::SystemTime; use std::{collections::BTreeMap, time::SystemTime};
use super::{Event, EventType, RoomEvent}; use super::{Event, EventType, RoomEvent};
use ruma_events_macros::FromRaw; use ruma_events_macros::FromRaw;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::Value;
/// A custom room event not covered by the Matrix specification. /// A custom room event not covered by the Matrix specification.
#[derive(Clone, Debug, FromRaw, PartialEq, Serialize)] #[derive(Clone, Debug, FromRaw, PartialEq, Serialize)]
@ -485,8 +486,8 @@ mod custom_room {
/// The unique identifier for the user who sent this event. /// The unique identifier for the user who sent this event.
pub sender: ruma_identifiers::UserId, pub sender: ruma_identifiers::UserId,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "serde_json::Map::is_empty")] #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `CustomRoomEvent`. /// The payload for `CustomRoomEvent`.
@ -532,7 +533,7 @@ mod custom_room {
} }
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
fn unsigned(&self) -> &Map<String, Value> { fn unsigned(&self) -> &BTreeMap<String, Value> {
&self.unsigned &self.unsigned
} }
} }
@ -559,19 +560,19 @@ mod custom_room {
pub sender: ruma_identifiers::UserId, pub sender: ruma_identifiers::UserId,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
} }
} }
mod custom_state { mod custom_state {
use std::time::SystemTime; use std::{collections::BTreeMap, time::SystemTime};
use super::{Event, EventType, RoomEvent, StateEvent}; use super::{Event, EventType, RoomEvent, StateEvent};
use ruma_events_macros::FromRaw; use ruma_events_macros::FromRaw;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::Value;
/// A custom state event not covered by the Matrix specification. /// A custom state event not covered by the Matrix specification.
#[derive(Clone, Debug, FromRaw, PartialEq, Serialize)] #[derive(Clone, Debug, FromRaw, PartialEq, Serialize)]
@ -595,8 +596,8 @@ mod custom_state {
/// A key that determines which piece of room state the event represents. /// A key that determines which piece of room state the event represents.
pub state_key: String, pub state_key: String,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "serde_json::Map::is_empty")] #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `CustomStateEvent`. /// The payload for `CustomStateEvent`.
@ -642,7 +643,7 @@ mod custom_state {
} }
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
fn unsigned(&self) -> &Map<String, Value> { fn unsigned(&self) -> &BTreeMap<String, Value> {
&self.unsigned &self.unsigned
} }
} }
@ -685,7 +686,7 @@ mod custom_state {
pub state_key: String, pub state_key: String,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
} }
} }

View File

@ -72,7 +72,7 @@ macro_rules! impl_room_event {
} }
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
fn unsigned(&self) -> &::serde_json::Map<String, ::serde_json::Value> { fn unsigned(&self) -> &::std::collections::BTreeMap<String, ::serde_json::Value> {
&self.unsigned &self.unsigned
} }
} }

View File

@ -1,6 +1,6 @@
//! Types for the *m.receipt* event. //! Types for the *m.receipt* event.
use std::{collections::HashMap, time::SystemTime}; use std::{collections::BTreeMap, time::SystemTime};
use ruma_events_macros::ruma_event; use ruma_events_macros::ruma_event;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
@ -23,7 +23,7 @@ ruma_event! {
/// ///
/// A mapping of event ID to a collection of receipts for this event ID. The event ID is the ID of /// A mapping of event ID to a collection of receipts for this event ID. The event ID is the ID of
/// the event being acknowledged and *not* an ID for the receipt itself. /// the event being acknowledged and *not* an ID for the receipt itself.
HashMap<EventId, Receipts> BTreeMap<EventId, Receipts>
}, },
} }
} }
@ -40,7 +40,7 @@ pub struct Receipts {
/// A mapping of user ID to receipt. /// A mapping of user ID to receipt.
/// ///
/// The user ID is the entity who sent this receipt. /// The user ID is the entity who sent this receipt.
pub type UserReceipts = HashMap<UserId, Receipt>; pub type UserReceipts = BTreeMap<UserId, Receipt>;
/// An acknowledgement of an event. /// An acknowledgement of an event.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]

View File

@ -2,7 +2,7 @@
//! //!
//! This module also contains types shared by events in its child namespaces. //! This module also contains types shared by events in its child namespaces.
use std::collections::HashMap; use std::collections::BTreeMap;
use js_int::UInt; use js_int::UInt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -97,7 +97,7 @@ pub struct EncryptedFile {
/// A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64. /// A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64.
/// Clients should support the SHA-256 hash, which uses the key sha256. /// Clients should support the SHA-256 hash, which uses the key sha256.
pub hashes: HashMap<String, String>, pub hashes: BTreeMap<String, String>,
/// Version of the encrypted attachments protocol. Must be `v2`. /// Version of the encrypted attachments protocol. Must be `v2`.
pub v: String, pub v: String,

View File

@ -1,6 +1,7 @@
//! Types for the *m.room.canonical_alias* event. //! Types for the *m.room.canonical_alias* event.
use std::{ use std::{
collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, UNIX_EPOCH},
}; };
@ -10,7 +11,7 @@ use serde::{
ser::{Error, SerializeStruct}, ser::{Error, SerializeStruct},
Deserialize, Serialize, Serializer, Deserialize, Serialize, Serializer,
}; };
use serde_json::{Map, Value}; use serde_json::Value;
use crate::{util::empty_string_as_none, Event, EventType, FromRaw}; use crate::{util::empty_string_as_none, Event, EventType, FromRaw};
@ -39,7 +40,7 @@ pub struct CanonicalAliasEvent {
pub state_key: String, pub state_key: String,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `CanonicalAliasEvent`. /// The payload for `CanonicalAliasEvent`.
@ -165,7 +166,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload of a `CanonicalAliasEvent`. /// The payload of a `CanonicalAliasEvent`.
@ -185,12 +186,13 @@ pub(crate) mod raw {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{ use std::{
collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
time::{Duration, UNIX_EPOCH}, time::{Duration, UNIX_EPOCH},
}; };
use ruma_identifiers::{EventId, RoomAliasId, UserId}; use ruma_identifiers::{EventId, RoomAliasId, UserId};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value, Map}; use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
use super::{CanonicalAliasEvent, CanonicalAliasEventContent}; use super::{CanonicalAliasEvent, CanonicalAliasEventContent};
use crate::EventResult; use crate::EventResult;
@ -207,7 +209,7 @@ mod tests {
room_id: None, room_id: None,
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "".to_string(), state_key: "".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
}; };
let actual = to_json_value(&canonical_alias_event).unwrap(); let actual = to_json_value(&canonical_alias_event).unwrap();

View File

@ -1,11 +1,11 @@
//! Types for the *m.room.encrypted* event. //! Types for the *m.room.encrypted* event.
use std::{collections::HashMap, time::SystemTime}; use std::{collections::BTreeMap, time::SystemTime};
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{DeviceId, EventId, RoomId, UserId}; use ruma_identifiers::{DeviceId, EventId, RoomId, UserId};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{from_value, Map, Value}; use serde_json::{from_value, Value};
use crate::{Algorithm, EventType, FromRaw}; use crate::{Algorithm, EventType, FromRaw};
@ -34,8 +34,8 @@ pub struct EncryptedEvent {
pub sender: UserId, pub sender: UserId,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "Map::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `EncryptedEvent`. /// The payload for `EncryptedEvent`.
@ -134,7 +134,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `EncryptedEvent`. /// The payload for `EncryptedEvent`.
@ -206,7 +206,7 @@ pub struct OlmV1Curve25519AesSha2Content {
pub algorithm: Algorithm, pub algorithm: Algorithm,
/// A map from the recipient Curve25519 identity key to ciphertext information. /// A map from the recipient Curve25519 identity key to ciphertext information.
pub ciphertext: HashMap<String, CiphertextInfo>, pub ciphertext: BTreeMap<String, CiphertextInfo>,
/// The Curve25519 key of the sender. /// The Curve25519 key of the sender.
pub sender_key: String, pub sender_key: String,

View File

@ -1,6 +1,6 @@
//! Types for the *m.room.member* event. //! Types for the *m.room.member* event.
use std::collections::HashMap; use std::collections::BTreeMap;
use ruma_events_macros::ruma_event; use ruma_events_macros::ruma_event;
use ruma_identifiers::UserId; use ruma_identifiers::UserId;
@ -123,7 +123,7 @@ pub struct SignedContent {
/// A single signature from the verifying server, in the format specified by the Signing Events /// A single signature from the verifying server, in the format specified by the Signing Events
/// section of the server-server API. /// section of the server-server API.
pub signatures: HashMap<String, HashMap<String, String>>, pub signatures: BTreeMap<String, BTreeMap<String, String>>,
/// The token property of the containing third_party_invite object. /// The token property of the containing third_party_invite object.
pub token: String, pub token: String,
@ -227,7 +227,7 @@ mod tests {
}; };
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde_json::{json, Map}; use serde_json::json;
use super::*; use super::*;
use crate::util::serde_json_eq_try_from_raw; use crate::util::serde_json_eq_try_from_raw;
@ -247,7 +247,7 @@ mod tests {
room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "example.com".to_string(), state_key: "example.com".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
prev_content: None, prev_content: None,
}; };
let json = json!({ let json = json!({
@ -279,7 +279,7 @@ mod tests {
room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "example.com".to_string(), state_key: "example.com".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
prev_content: Some(MemberEventContent { prev_content: Some(MemberEventContent {
avatar_url: None, avatar_url: None,
displayname: None, displayname: None,
@ -335,7 +335,7 @@ mod tests {
room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()), room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()),
sender: UserId::try_from("@alice:example.org").unwrap(), sender: UserId::try_from("@alice:example.org").unwrap(),
state_key: "@alice:example.org".to_string(), state_key: "@alice:example.org".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
prev_content: None, prev_content: None,
}; };
let json = json!({ let json = json!({
@ -390,7 +390,7 @@ mod tests {
room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()), room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()),
sender: UserId::try_from("@alice:example.org").unwrap(), sender: UserId::try_from("@alice:example.org").unwrap(),
state_key: "@alice:example.org".to_string(), state_key: "@alice:example.org".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
prev_content: Some(MemberEventContent { prev_content: Some(MemberEventContent {
avatar_url: Some("mxc://example.org/SEsfnsuifSDFSSEF".to_owned()), avatar_url: Some("mxc://example.org/SEsfnsuifSDFSSEF".to_owned()),
displayname: Some("Alice Margatroid".to_owned()), displayname: Some("Alice Margatroid".to_owned()),

View File

@ -1,11 +1,11 @@
//! Types for the *m.room.message* event. //! Types for the *m.room.message* event.
use std::time::SystemTime; use std::{collections::BTreeMap, time::SystemTime};
use js_int::UInt; use js_int::UInt;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{from_value, Map, Value}; use serde_json::{from_value, Value};
use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
use crate::{EventType, FromRaw}; use crate::{EventType, FromRaw};
@ -34,8 +34,8 @@ pub struct MessageEvent {
pub sender: UserId, pub sender: UserId,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "Map::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `MessageEvent`. /// The payload for `MessageEvent`.
@ -163,7 +163,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `MessageEvent`. /// The payload for `MessageEvent`.

View File

@ -1,10 +1,10 @@
//! Types for the *m.room.name* event. //! Types for the *m.room.name* event.
use std::time::SystemTime; use std::{collections::BTreeMap, time::SystemTime};
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::Value;
use crate::{util::empty_string_as_none, EventType, InvalidInput, TryFromRaw}; use crate::{util::empty_string_as_none, EventType, InvalidInput, TryFromRaw};
@ -37,8 +37,8 @@ pub struct NameEvent {
pub state_key: String, pub state_key: String,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "Map::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `NameEvent`. /// The payload for `NameEvent`.
@ -136,7 +136,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload of a `NameEvent`. /// The payload of a `NameEvent`.
@ -154,13 +154,14 @@ pub(crate) mod raw {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{ use std::{
collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
iter::FromIterator, iter::FromIterator,
time::{Duration, UNIX_EPOCH}, time::{Duration, UNIX_EPOCH},
}; };
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value, Map}; use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
use crate::EventResult; use crate::EventResult;
@ -178,7 +179,7 @@ mod tests {
room_id: None, room_id: None,
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "".to_string(), state_key: "".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
}; };
let actual = to_json_value(&name_event).unwrap(); let actual = to_json_value(&name_event).unwrap();

View File

@ -17,10 +17,13 @@ ruma_event! {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::time::{Duration, UNIX_EPOCH}; use std::{
collections::BTreeMap,
time::{Duration, UNIX_EPOCH},
};
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde_json::{to_string, Map}; use serde_json::to_string;
use crate::{ use crate::{
room::pinned_events::{PinnedEventsEvent, PinnedEventsEventContent}, room::pinned_events::{PinnedEventsEvent, PinnedEventsEventContent},
@ -42,7 +45,7 @@ mod tests {
room_id: Some(RoomId::new("example.com").unwrap()), room_id: Some(RoomId::new("example.com").unwrap()),
sender: UserId::new("example.com").unwrap(), sender: UserId::new("example.com").unwrap(),
state_key: "".to_string(), state_key: "".to_string(),
unsigned: Map::new(), unsigned: BTreeMap::new(),
}; };
let serialized_event = to_string(&event).unwrap(); let serialized_event = to_string(&event).unwrap();

View File

@ -1,11 +1,11 @@
//! Types for the *m.room.power_levels* event. //! Types for the *m.room.power_levels* event.
use std::{collections::HashMap, time::SystemTime}; use std::{collections::BTreeMap, time::SystemTime};
use js_int::Int; use js_int::Int;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::Value;
use crate::{EventType, FromRaw}; use crate::{EventType, FromRaw};
@ -32,8 +32,8 @@ pub struct PowerLevelsEvent {
pub room_id: Option<RoomId>, pub room_id: Option<RoomId>,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "Map::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
/// The unique identifier for the user who sent this event. /// The unique identifier for the user who sent this event.
pub sender: UserId, pub sender: UserId,
@ -52,8 +52,8 @@ pub struct PowerLevelsEventContent {
/// The level required to send specific event types. /// The level required to send specific event types.
/// ///
/// This is a mapping from event type to power level required. /// This is a mapping from event type to power level required.
#[serde(skip_serializing_if = "HashMap::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub events: HashMap<EventType, Int>, pub events: BTreeMap<EventType, Int>,
/// The default level required to send message events. /// The default level required to send message events.
#[serde(skip_serializing_if = "is_power_level_zero")] #[serde(skip_serializing_if = "is_power_level_zero")]
@ -78,8 +78,8 @@ pub struct PowerLevelsEventContent {
/// The power levels for specific users. /// The power levels for specific users.
/// ///
/// This is a mapping from `user_id` to power level for that user. /// This is a mapping from `user_id` to power level for that user.
#[serde(skip_serializing_if = "HashMap::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub users: HashMap<UserId, Int>, pub users: BTreeMap<UserId, Int>,
/// The default power level for every user in the room. /// The default power level for every user in the room.
#[serde(skip_serializing_if = "is_power_level_zero")] #[serde(skip_serializing_if = "is_power_level_zero")]
@ -158,7 +158,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
/// The unique identifier for the user who sent this event. /// The unique identifier for the user who sent this event.
pub sender: UserId, pub sender: UserId,
@ -178,7 +178,7 @@ pub(crate) mod raw {
/// ///
/// This is a mapping from event type to power level required. /// This is a mapping from event type to power level required.
#[serde(default)] #[serde(default)]
pub events: HashMap<EventType, Int>, pub events: BTreeMap<EventType, Int>,
/// The default level required to send message events. /// The default level required to send message events.
#[serde(default)] #[serde(default)]
@ -204,7 +204,7 @@ pub(crate) mod raw {
/// ///
/// This is a mapping from `user_id` to power level for that user. /// This is a mapping from `user_id` to power level for that user.
#[serde(default)] #[serde(default)]
pub users: HashMap<UserId, Int>, pub users: BTreeMap<UserId, Int>,
/// The default power level for every user in the room. /// The default power level for every user in the room.
#[serde(default)] #[serde(default)]
@ -263,15 +263,15 @@ fn is_power_level_zero(l: &Int) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{ use std::{
collections::HashMap, collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
time::{Duration, UNIX_EPOCH}, time::{Duration, UNIX_EPOCH},
}; };
use js_int::Int; use js_int::Int;
use maplit::hashmap; use maplit::btreemap;
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde_json::{json, to_value as to_json_value, Map}; use serde_json::{json, to_value as to_json_value};
use super::{ use super::{
default_power_level, NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent, default_power_level, NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent,
@ -285,13 +285,13 @@ mod tests {
let power_levels_event = PowerLevelsEvent { let power_levels_event = PowerLevelsEvent {
content: PowerLevelsEventContent { content: PowerLevelsEventContent {
ban: default, ban: default,
events: HashMap::new(), events: BTreeMap::new(),
events_default: Int::from(0), events_default: Int::from(0),
invite: default, invite: default,
kick: default, kick: default,
redact: default, redact: default,
state_default: default, state_default: default,
users: HashMap::new(), users: BTreeMap::new(),
users_default: Int::from(0), users_default: Int::from(0),
notifications: NotificationPowerLevels::default(), notifications: NotificationPowerLevels::default(),
}, },
@ -299,7 +299,7 @@ mod tests {
origin_server_ts: UNIX_EPOCH + Duration::from_millis(1), origin_server_ts: UNIX_EPOCH + Duration::from_millis(1),
prev_content: None, prev_content: None,
room_id: None, room_id: None,
unsigned: Map::new(), unsigned: BTreeMap::new(),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "".to_string(), state_key: "".to_string(),
}; };
@ -323,7 +323,7 @@ mod tests {
let power_levels_event = PowerLevelsEvent { let power_levels_event = PowerLevelsEvent {
content: PowerLevelsEventContent { content: PowerLevelsEventContent {
ban: Int::from(23), ban: Int::from(23),
events: hashmap! { events: btreemap! {
EventType::Dummy => Int::from(23) EventType::Dummy => Int::from(23)
}, },
events_default: Int::from(23), events_default: Int::from(23),
@ -331,7 +331,7 @@ mod tests {
kick: Int::from(23), kick: Int::from(23),
redact: Int::from(23), redact: Int::from(23),
state_default: Int::from(23), state_default: Int::from(23),
users: hashmap! { users: btreemap! {
user.clone() => Int::from(23) user.clone() => Int::from(23)
}, },
users_default: Int::from(23), users_default: Int::from(23),
@ -344,7 +344,7 @@ mod tests {
prev_content: Some(PowerLevelsEventContent { prev_content: Some(PowerLevelsEventContent {
// 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.
ban: Int::from(42), ban: Int::from(42),
events: hashmap! { events: btreemap! {
EventType::Dummy => Int::from(42) EventType::Dummy => Int::from(42)
}, },
events_default: Int::from(42), events_default: Int::from(42),
@ -352,7 +352,7 @@ mod tests {
kick: Int::from(42), kick: Int::from(42),
redact: Int::from(42), redact: Int::from(42),
state_default: Int::from(42), state_default: Int::from(42),
users: hashmap! { users: btreemap! {
user.clone() => Int::from(42) user.clone() => Int::from(42)
}, },
users_default: Int::from(42), users_default: Int::from(42),

View File

@ -1,10 +1,10 @@
//! Types for the *m.room.server_acl* event. //! Types for the *m.room.server_acl* event.
use std::time::SystemTime; use std::{collections::BTreeMap, time::SystemTime};
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomId, UserId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::Value;
use crate::{util::default_true, EventType, FromRaw}; use crate::{util::default_true, EventType, FromRaw};
@ -37,8 +37,8 @@ pub struct ServerAclEvent {
pub state_key: String, pub state_key: String,
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(skip_serializing_if = "Map::is_empty")] #[serde(skip_serializing_if = "BTreeMap::is_empty")]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
} }
/// The payload for `ServerAclEvent`. /// The payload for `ServerAclEvent`.
@ -129,7 +129,7 @@ pub(crate) mod raw {
/// Additional key-value pairs not signed by the homeserver. /// Additional key-value pairs not signed by the homeserver.
#[serde(default)] #[serde(default)]
pub unsigned: Map<String, Value>, pub unsigned: BTreeMap<String, Value>,
/// The unique identifier for the user who sent this event. /// The unique identifier for the user who sent this event.
pub sender: UserId, pub sender: UserId,

View File

@ -1,6 +1,6 @@
//! Types for the *m.tag* event. //! Types for the *m.tag* event.
use std::collections::HashMap; use std::collections::BTreeMap;
use ruma_events_macros::ruma_event; use ruma_events_macros::ruma_event;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -12,7 +12,7 @@ ruma_event! {
event_type: "m.tag", event_type: "m.tag",
content: { content: {
/// A map of tag names to tag info. /// A map of tag names to tag info.
pub tags: HashMap<String, TagInfo>, pub tags: BTreeMap<String, TagInfo>,
}, },
} }
} }

View File

@ -72,7 +72,7 @@ where
} }
} }
/// Serde serialization and deserialization functions that map a `Vec<T>` to a `HashMap<T, Empty>`. /// Serde serialization and deserialization functions that map a `Vec<T>` to a `BTreeMap<T, Empty>`.
/// ///
/// The Matrix spec sometimes specifies lists as hash maps so the list entries can be expanded with /// The Matrix spec sometimes specifies lists as hash maps so the list entries can be expanded with
/// attributes without breaking compatibility. As that would be a breaking change for ruma's event /// attributes without breaking compatibility. As that would be a breaking change for ruma's event
@ -80,28 +80,30 @@ where
/// ///
/// To be used as `#[serde(with = "vec_as_map_of_empty")]`. /// To be used as `#[serde(with = "vec_as_map_of_empty")]`.
pub mod vec_as_map_of_empty { pub mod vec_as_map_of_empty {
use crate::Empty; use std::collections::BTreeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{collections::HashMap, hash::Hash};
use crate::Empty;
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub fn serialize<S, T>(vec: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error> pub fn serialize<S, T>(vec: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
T: Serialize + Hash + Eq, T: Serialize + Eq + Ord,
{ {
vec.iter() vec.iter()
.map(|v| (v, Empty)) .map(|v| (v, Empty))
.collect::<HashMap<_, _>>() .collect::<BTreeMap<_, _>>()
.serialize(serializer) .serialize(serializer)
} }
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error> pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
T: Deserialize<'de> + Hash + Eq, T: Deserialize<'de> + Eq + Ord,
{ {
HashMap::<T, Empty>::deserialize(deserializer) BTreeMap::<T, Empty>::deserialize(deserializer)
.map(|hashmap| hashmap.into_iter().map(|(k, _)| k).collect()) .map(|hashmap| hashmap.into_iter().map(|(k, _)| k).collect())
} }
} }

View File

@ -1,5 +1,5 @@
use std::{ use std::{
collections::HashMap, collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
time::{Duration, UNIX_EPOCH}, time::{Duration, UNIX_EPOCH},
}; };
@ -37,7 +37,7 @@ mod common_case {
room_id: None, room_id: None,
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "example.com".to_string(), state_key: "example.com".to_string(),
unsigned: serde_json::Map::new(), unsigned: std::collections::BTreeMap::new(),
}; };
let json = json!({ let json = json!({
"content": { "content": {
@ -66,7 +66,7 @@ mod common_case {
room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()),
sender: UserId::try_from("@carl:example.com").unwrap(), sender: UserId::try_from("@carl:example.com").unwrap(),
state_key: "example.com".to_string(), state_key: "example.com".to_string(),
unsigned: serde_json::Map::new(), unsigned: std::collections::BTreeMap::new(),
}; };
let json = json!({ let json = json!({
"content": { "content": {
@ -183,7 +183,7 @@ mod type_alias {
/// ///
/// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered /// A mapping of `UserId`'s to a collection of `RoomId`'s which are considered
/// *direct* for that particular user. /// *direct* for that particular user.
HashMap<ruma_identifiers::UserId, Vec<ruma_identifiers::RoomId>> BTreeMap<ruma_identifiers::UserId, Vec<ruma_identifiers::RoomId>>
} }
} }
} }