Merge pull request #10 from jevolk/conduwuit-changes

structured Mxc type
This commit is contained in:
June 🍓🦴 2024-08-15 23:30:25 -04:00 committed by GitHub
commit 01e910dccf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 54 additions and 24 deletions

View File

@ -13,7 +13,7 @@ pub mod v1 {
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -101,7 +101,7 @@ pub mod v1 {
/// Creates a new `Request` with the given URI. /// Creates a new `Request` with the given URI.
pub fn from_uri(uri: &MxcUri) -> Result<Self, IdParseError> { pub fn from_uri(uri: &MxcUri) -> Result<Self, IdParseError> {
let (server_name, media_id) = uri.parts()?; let Mxc { server_name, media_id } = uri.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned())) Ok(Self::new(media_id.to_owned(), server_name.to_owned()))
} }

View File

@ -13,7 +13,7 @@ pub mod v1 {
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -106,7 +106,7 @@ pub mod v1 {
/// Creates a new `Request` with the given URI and filename. /// Creates a new `Request` with the given URI and filename.
pub fn from_uri(uri: &MxcUri, filename: String) -> Result<Self, IdParseError> { pub fn from_uri(uri: &MxcUri, filename: String) -> Result<Self, IdParseError> {
let (server_name, media_id) = uri.parts()?; let Mxc { server_name, media_id } = uri.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned(), filename)) Ok(Self::new(media_id.to_owned(), server_name.to_owned(), filename))
} }

View File

@ -15,7 +15,7 @@ pub mod v1 {
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
media::Method, media::Method,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -140,7 +140,7 @@ pub mod v1 {
/// Creates a new `Request` with the given URI, desired thumbnail width and /// Creates a new `Request` with the given URI, desired thumbnail width and
/// desired thumbnail height. /// desired thumbnail height.
pub fn from_uri(uri: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> { pub fn from_uri(uri: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
let (server_name, media_id) = uri.parts()?; let Mxc { server_name, media_id } = uri.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height)) Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height))
} }

View File

@ -10,7 +10,7 @@ pub mod v3 {
use http::header::CONTENT_TYPE; use http::header::CONTENT_TYPE;
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
@ -61,7 +61,7 @@ pub mod v3 {
/// Creates a new `Request` with the given url and file contents. /// Creates a new `Request` with the given url and file contents.
pub fn from_url(url: &MxcUri, file: Vec<u8>) -> Result<Self, IdParseError> { pub fn from_url(url: &MxcUri, file: Vec<u8>) -> Result<Self, IdParseError> {
let (server_name, media_id) = url.parts()?; let Mxc { server_name, media_id } = url.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned(), file)) Ok(Self::new(media_id.to_owned(), server_name.to_owned(), file))
} }
} }

View File

@ -13,7 +13,7 @@ pub mod v3 {
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -123,7 +123,7 @@ pub mod v3 {
/// Creates a new `Request` with the given url. /// Creates a new `Request` with the given url.
pub fn from_url(url: &MxcUri) -> Result<Self, IdParseError> { pub fn from_url(url: &MxcUri) -> Result<Self, IdParseError> {
let (server_name, media_id) = url.parts()?; let Mxc { server_name, media_id } = url.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned())) Ok(Self::new(media_id.to_owned(), server_name.to_owned()))
} }

View File

@ -13,7 +13,7 @@ pub mod v3 {
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -128,7 +128,7 @@ pub mod v3 {
/// Creates a new `Request` with the given url and filename. /// Creates a new `Request` with the given url and filename.
pub fn from_url(url: &MxcUri, filename: String) -> Result<Self, IdParseError> { pub fn from_url(url: &MxcUri, filename: String) -> Result<Self, IdParseError> {
let (server_name, media_id) = url.parts()?; let Mxc { server_name, media_id } = url.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned(), filename)) Ok(Self::new(media_id.to_owned(), server_name.to_owned(), filename))
} }

View File

@ -15,7 +15,7 @@ pub mod v3 {
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
http_headers::ContentDisposition, http_headers::ContentDisposition,
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, Mxc, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY; use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
@ -166,7 +166,7 @@ pub mod v3 {
/// Creates a new `Request` with the given url, desired thumbnail width and /// Creates a new `Request` with the given url, desired thumbnail width and
/// desired thumbnail height. /// desired thumbnail height.
pub fn from_url(url: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> { pub fn from_url(url: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
let (server_name, media_id) = url.parts()?; let Mxc { server_name, media_id } = url.parts()?;
Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height)) Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height))
} }

View File

@ -26,7 +26,7 @@ pub use self::{
}, },
key_name::{KeyName, OwnedKeyName}, key_name::{KeyName, OwnedKeyName},
matrix_uri::{MatrixToUri, MatrixUri}, matrix_uri::{MatrixToUri, MatrixUri},
mxc_uri::{MxcUri, OwnedMxcUri}, mxc_uri::{Mxc, MxcUri, OwnedMxcUri},
room_alias_id::{OwnedRoomAliasId, RoomAliasId}, room_alias_id::{OwnedRoomAliasId, RoomAliasId},
room_id::{OwnedRoomId, RoomId}, room_id::{OwnedRoomId, RoomId},
room_or_alias_id::{OwnedRoomOrAliasId, RoomOrAliasId}, room_or_alias_id::{OwnedRoomOrAliasId, RoomOrAliasId},

View File

@ -2,7 +2,7 @@
//! //!
//! [MXC URI]: https://spec.matrix.org/latest/client-server-api/#matrix-content-mxc-uris //! [MXC URI]: https://spec.matrix.org/latest/client-server-api/#matrix-content-mxc-uris
use std::num::NonZeroU8; use std::{fmt, num::NonZeroU8};
use ruma_identifiers_validation::{error::MxcUriError, mxc_uri::validate}; use ruma_identifiers_validation::{error::MxcUriError, mxc_uri::validate};
use ruma_macros::IdZst; use ruma_macros::IdZst;
@ -18,25 +18,33 @@ type Result<T, E = MxcUriError> = std::result::Result<T, E>;
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdZst)]
pub struct MxcUri(str); pub struct MxcUri(str);
/// Structured MXC URI which may reference strings from separate sources without serialization
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Mxc<'a> {
/// ServerName part of the MXC URI
pub server_name: &'a ServerName,
/// MediaId part of the MXC URI
pub media_id: &'a str,
}
impl MxcUri { impl MxcUri {
/// If this is a valid MXC URI, returns the media ID. /// If this is a valid MXC URI, returns the media ID.
pub fn media_id(&self) -> Result<&str> { pub fn media_id(&self) -> Result<&str> {
self.parts().map(|(_, s)| s) self.parts().map(|mxc| mxc.media_id)
} }
/// If this is a valid MXC URI, returns the server name. /// If this is a valid MXC URI, returns the server name.
pub fn server_name(&self) -> Result<&ServerName> { pub fn server_name(&self) -> Result<&ServerName> {
self.parts().map(|(s, _)| s) self.parts().map(|mxc| mxc.server_name)
} }
/// If this is a valid MXC URI, returns a `(server_name, media_id)` tuple, else it returns the /// If this is a valid MXC URI, returns a `(server_name, media_id)` tuple, else it returns the
/// error. /// error.
pub fn parts(&self) -> Result<(&ServerName, &str)> { pub fn parts(&self) -> Result<Mxc<'_>> {
self.extract_slash_idx().map(|idx| { self.extract_slash_idx().map(|idx| Mxc::<'_> {
( server_name: ServerName::from_borrowed(&self.as_str()[6..idx.get() as usize]),
ServerName::from_borrowed(&self.as_str()[6..idx.get() as usize]), media_id: &self.as_str()[idx.get() as usize + 1..],
&self.as_str()[idx.get() as usize + 1..],
)
}) })
} }
@ -58,6 +66,28 @@ impl MxcUri {
} }
} }
impl fmt::Display for Mxc<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "mxc://{}/{}", self.server_name, self.media_id)
}
}
impl<'a> TryFrom<&'a MxcUri> for Mxc<'a> {
type Error = MxcUriError;
fn try_from(s: &'a MxcUri) -> Result<Self, Self::Error> {
s.parts()
}
}
impl<'a> TryFrom<&'a str> for Mxc<'a> {
type Error = MxcUriError;
fn try_from(s: &'a str) -> Result<Self, Self::Error> {
s.try_into()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ruma_identifiers_validation::error::MxcUriError; use ruma_identifiers_validation::error::MxcUriError;