use std::{
convert::TryFrom,
fmt::{self, Display},
str::FromStr,
};
use http::Method;
use crate::{error::UnknownVersionError, AuthScheme};
#[derive(Clone, Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct Metadata {
pub description: &'static str,
pub method: Method,
pub name: &'static str,
pub unstable_path: Option<&'static str>,
pub r0_path: Option<&'static str>,
pub stable_path: Option<&'static str>,
pub rate_limited: bool,
pub authentication: AuthScheme,
pub added: Option<MatrixVersion>,
pub deprecated: Option<MatrixVersion>,
pub removed: Option<MatrixVersion>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub enum MatrixVersion {
V1_0,
V1_1,
V1_2,
}
impl TryFrom<&str> for MatrixVersion {
type Error = UnknownVersionError;
fn try_from(value: &str) -> Result<MatrixVersion, Self::Error> {
use MatrixVersion::*;
Ok(match value {
"v1.0" |
"r0.5.0" | "r0.6.0" | "r0.6.1" => V1_0,
"v1.1" => V1_1,
"v1.2" => V1_2,
_ => return Err(UnknownVersionError),
})
}
}
impl FromStr for MatrixVersion {
type Err = UnknownVersionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_from(s)
}
}
impl MatrixVersion {
pub fn is_superset_of(self, other: Self) -> bool {
let (major_l, minor_l) = self.into_parts();
let (major_r, minor_r) = other.into_parts();
major_l == major_r && minor_l >= minor_r
}
pub fn into_parts(self) -> (u8, u8) {
match self {
MatrixVersion::V1_0 => (1, 0),
MatrixVersion::V1_1 => (1, 1),
MatrixVersion::V1_2 => (1, 2),
}
}
pub fn from_parts(major: u8, minor: u8) -> Result<Self, UnknownVersionError> {
match (major, minor) {
(1, 0) => Ok(MatrixVersion::V1_0),
(1, 1) => Ok(MatrixVersion::V1_1),
(1, 2) => Ok(MatrixVersion::V1_2),
_ => Err(UnknownVersionError),
}
}
}
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))
}
}