Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions crates/ruma-client-api/src/discovery/get_supported_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use ruma_common::{
api::{request, response, Metadata, SupportedVersions},
metadata,
};
use smallstr::SmallString;

const METADATA: Metadata = metadata! {
method: GET,
Expand All @@ -29,16 +30,22 @@ pub struct Request {}
#[response(error = crate::Error)]
pub struct Response {
/// A list of Matrix client API protocol versions supported by the homeserver.
pub versions: Vec<String>,
pub versions: Vec<Version>,

/// Experimental features supported by the server.
///
/// Servers can enable some unstable features only for some users, so this
/// list might differ when an access token is provided.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub unstable_features: BTreeMap<String, bool>,
pub unstable_features: BTreeMap<Feature, bool>,
}

/// Opinionated optimized Version String type.
pub type Version = SmallString<[u8; 16]>;

/// Opinionated optimized Feature String type.
pub type Feature = SmallString<[u8; 48]>;

impl Request {
/// Creates an empty `Request`.
pub fn new() -> Self {
Expand All @@ -48,7 +55,7 @@ impl Request {

impl Response {
/// Creates a new `Response` with the given `versions`.
pub fn new(versions: Vec<String>) -> Self {
pub fn new(versions: Vec<Version>) -> Self {
Self { versions, unstable_features: BTreeMap::new() }
}

Expand All @@ -58,6 +65,9 @@ impl Response {
/// Matrix versions that can't be parsed to a `MatrixVersion`, and features with the boolean
/// value set to `false` are discarded.
pub fn as_supported_versions(&self) -> SupportedVersions {
SupportedVersions::from_parts(&self.versions, &self.unstable_features)
SupportedVersions::from_parts(
self.versions.iter().map(Version::as_str),
self.unstable_features.iter().map(|(k, v)| (k.as_str(), v)),
)
}
}
2 changes: 0 additions & 2 deletions crates/ruma-client-api/src/membership/joined_members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,12 @@ pub mod v3 {
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
pub struct RoomMember {
/// The display name of the user.
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,

/// The mxc avatar url of the user.
///
/// If you activate the `compat-empty-string-null` feature, this field being an empty
/// string in JSON will result in `None` here during deserialization.
#[serde(skip_serializing_if = "Option::is_none")]
#[cfg_attr(
feature = "compat-empty-string-null",
serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")
Expand Down
1 change: 1 addition & 0 deletions crates/ruma-client-api/src/sync/sync_events/v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ pub mod request {
pub required_state: Vec<(StateEventType, StateKey)>,

/// The maximum number of timeline events to return per room.
#[serde(default)]
pub timeline_limit: UInt,
}

Expand Down
16 changes: 11 additions & 5 deletions crates/ruma-common/src/api/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
cmp::Ordering,
collections::{BTreeMap, BTreeSet},
collections::BTreeSet,
fmt::{Display, Write},
str::FromStr,
};
Expand Down Expand Up @@ -1144,13 +1144,19 @@ impl SupportedVersions {
///
/// Matrix versions that can't be parsed to a `MatrixVersion`, and features with the boolean
/// value set to `false` are discarded.
pub fn from_parts(versions: &[String], unstable_features: &BTreeMap<String, bool>) -> Self {
pub fn from_parts<'a, Versions, Features>(
versions: Versions,
unstable_features: Features,
) -> Self
where
Versions: Iterator<Item = &'a str>,
Features: Iterator<Item = (&'a str, &'a bool)>,
{
Self {
versions: versions.iter().flat_map(|s| s.parse::<MatrixVersion>()).collect(),
versions: versions.flat_map(|s| s.parse::<MatrixVersion>()).collect(),
features: unstable_features
.iter()
.filter(|(_, enabled)| **enabled)
.map(|(feature, _)| feature.as_str().into())
.map(|(feature, _)| feature.into())
.collect(),
}
}
Expand Down
11 changes: 7 additions & 4 deletions crates/ruma-common/src/push/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,13 +503,16 @@ impl StrExt for str {
}

fn matches_pattern(&self, pattern: &str, match_words: bool) -> bool {
let value = &self.to_lowercase();
let pattern = &pattern.to_lowercase();

if match_words {
if self.eq_ignore_ascii_case(pattern) {
return true;
}

let value = &self.to_lowercase();
let pattern = &pattern.to_lowercase();
value.matches_word(pattern)
} else {
WildMatch::new(pattern).matches(value)
WildMatch::new_case_insensitive(pattern).matches(self)
}
}

Expand Down
5 changes: 5 additions & 0 deletions crates/ruma-events/src/room/canonical_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ impl RoomCanonicalAliasEventContent {
pub fn new() -> Self {
Self { alias: None, alt_aliases: Vec::new() }
}

/// Returns an iterator over the canonical alias and alt aliases
pub fn aliases(&self) -> impl Iterator<Item = &OwnedRoomAliasId> {
self.alias.iter().chain(self.alt_aliases.iter())
}
}

#[cfg(test)]
Expand Down
19 changes: 17 additions & 2 deletions crates/ruma-events/src/room/server_acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ impl RoomServerAclEventContent {
}

fn matches(a: &[String], s: &str) -> bool {
a.iter().map(String::as_str).any(|a| WildMatch::new(a).matches(s))
a.iter().map(String::as_str).any(|a| WildMatch::new_case_insensitive(a).matches(s))
}

fn contains(a: &[String], s: &str) -> bool {
a.iter().map(String::as_str).any(|a| a == s)
a.iter().map(String::as_str).any(|a| a.eq_ignore_ascii_case(s))
}
}

Expand Down Expand Up @@ -222,4 +222,19 @@ mod tests {
assert!(!acl_event.is_allowed(server_name!("[2001:db8:1234::2]")));
assert!(acl_event.is_allowed(server_name!("[2001:db8:1234::1]")));
}

#[test]
fn acl_case_insensitive() {
let acl_event = RoomServerAclEventContent {
allow_ip_literals: false,
allow: vec!["good.ServEr".to_owned()],
deny: vec!["bad.ServeR".to_owned()],
};
assert!(!acl_event.is_allowed(server_name!("Bad.ServeR")));
assert!(!acl_event.is_allowed(server_name!("bAD.sERvER")));
assert!(!acl_event.is_allowed(server_name!("bAd.server")));
assert!(acl_event.is_allowed(server_name!("good.ServEr")));
assert!(acl_event.is_allowed(server_name!("good.server")));
assert!(acl_event.is_allowed(server_name!("GOOD.SERVER")));
}
}
1 change: 1 addition & 0 deletions crates/ruma-identity-service-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ js_int = { workspace = true, features = ["serde"] }
ruma-common = { workspace = true, features = ["api"] }
ruma-events = { workspace = true }
serde = { workspace = true }
smallstr = { workspace = true }

[dev-dependencies]
serde_json = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use ruma_common::{
api::{request, response, Metadata, SupportedVersions},
metadata,
};
use smallstr::SmallString;

const METADATA: Metadata = metadata! {
method: GET,
Expand All @@ -35,9 +36,15 @@ pub struct Request {}
#[response]
pub struct Response {
/// A list of Matrix client API protocol versions supported by the endpoint.
pub versions: Vec<String>,
pub versions: Vec<Version>,
}

/// Opinionated optimized Version String type.
pub type Version = SmallString<[u8; 16]>;

/// Opinionated optimized Feature String type.
pub type Feature = SmallString<[u8; 48]>;

impl Request {
/// Creates an empty `Request`.
pub fn new() -> Self {
Expand All @@ -47,7 +54,7 @@ impl Request {

impl Response {
/// Creates a new `Response` with the given `versions`.
pub fn new(versions: Vec<String>) -> Self {
pub fn new(versions: Vec<Version>) -> Self {
Self { versions }
}

Expand All @@ -57,6 +64,9 @@ impl Response {
/// Matrix versions that can't be parsed to a `MatrixVersion`, and features with the boolean
/// value set to `false` are discarded.
pub fn as_supported_versions(&self) -> SupportedVersions {
SupportedVersions::from_parts(&self.versions, &BTreeMap::new())
SupportedVersions::from_parts(
self.versions.iter().map(Version::as_str),
BTreeMap::<Feature, bool>::new().iter().map(|(k, v)| (k.as_str(), v)),
)
}
}