api: Replace Display implementation of MatrixVersion with as_str() method

Because it is not correct to convert V1_0 to a string.
This commit is contained in:
Kévin Commaille 2025-01-24 04:55:38 +01:00 committed by strawberry
parent b91034f8a0
commit 990d01b19d
3 changed files with 68 additions and 9 deletions

View file

@ -1,5 +1,30 @@
# [unreleased]
=======
Breaking changes:
- `UserId` parsing and deserialization are now compatible with all non-compliant
user IDs in the wild by default, due to a clarification in the spec.
- The `compat-user-id` cargo feature was removed.
- `UserId::validate_historical()` and `UserId::validate_strict()` allow to
check for spec compliance.
- The `(owned_)user_id!` macros always validate against the strict grammar in
the spec, regardless of the compat features that are enabled.
- `(owned_)room_id!` macros disallow the `NUL` byte, due to a clarification in
the spec.
- `(owned_)room_alias_id!` macros disallow the `NUL` byte for the localpart, due
to a clarification in the spec.
- `MatrixVersion` does not implement `Display` anymore as it is not correct to
convert `V1_0` to a string. Instead `MatrixVersion::as_str()` can be used that
only returns `None` for that same variant.
Improvements:
- `MatrixVersion` implements `PartialOrd` and `Ord`. The variants are ordered by
release date, with a newer version being greater than an older version.
# 0.15.1
Improvements:
- Add `MatrixVersion::V1_13`.

View file

@ -113,7 +113,10 @@ pub enum IntoHttpError {
/// Tried to create a request with [`MatrixVersion`]s for all of which this endpoint was
/// removed.
#[error("could not create any path variant for endpoint, as it was removed in version {0}")]
#[error(
"could not create any path variant for endpoint, as it was removed in version {}",
.0.as_str().expect("no endpoint was removed in Matrix 1.0")
)]
EndpointRemoved(MatrixVersion),
/// JSON serialization failed.

View file

@ -1,6 +1,6 @@
use std::{
cmp::Ordering,
fmt::{self, Display, Write},
fmt::{Display, Write},
str::FromStr,
};
@ -631,6 +631,33 @@ impl MatrixVersion {
self >= other
}
/// Get a string representation of this Matrix version.
///
/// This is the string that can be found in the response to one of the `GET /versions`
/// endpoints. Parsing this string will give the same variant.
///
/// Returns `None` for [`MatrixVersion::V1_0`] because it can match several per-API versions.
pub const fn as_str(self) -> Option<&'static str> {
let string = match self {
MatrixVersion::V1_0 => return None,
MatrixVersion::V1_1 => "v1.1",
MatrixVersion::V1_2 => "v1.2",
MatrixVersion::V1_3 => "v1.3",
MatrixVersion::V1_4 => "v1.4",
MatrixVersion::V1_5 => "v1.5",
MatrixVersion::V1_6 => "v1.6",
MatrixVersion::V1_7 => "v1.7",
MatrixVersion::V1_8 => "v1.8",
MatrixVersion::V1_9 => "v1.9",
MatrixVersion::V1_10 => "v1.10",
MatrixVersion::V1_11 => "v1.11",
MatrixVersion::V1_12 => "v1.12",
MatrixVersion::V1_13 => "v1.13",
};
Some(string)
}
/// Decompose the Matrix version into its major and minor number.
pub const fn into_parts(self) -> (u8, u8) {
match self {
@ -773,13 +800,6 @@ impl MatrixVersion {
}
}
impl Display for MatrixVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (major, minor) = self.into_parts();
f.write_str(&format!("v{major}.{minor}"))
}
}
#[cfg(test)]
mod tests {
use assert_matches2::assert_matches;
@ -906,4 +926,15 @@ mod tests {
assert_eq!(LIT, V1_0);
}
#[test]
fn parse_as_str_sanity() {
let version = MatrixVersion::try_from("r0.5.0").unwrap();
assert_eq!(version, V1_0);
assert_eq!(version.as_str(), None);
let version = MatrixVersion::try_from("v1.1").unwrap();
assert_eq!(version, V1_1);
assert_eq!(version.as_str(), Some("v1.1"));
}
}