identifiers: Make MxcUri a DST

This commit is contained in:
Jonas Platte 2021-09-18 00:39:36 +02:00
parent a38f78e2d3
commit ec605a0959
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
25 changed files with 70 additions and 127 deletions

View File

@ -54,7 +54,7 @@ pub struct PublicRoomsChunk {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The joining rule for the room.
#[cfg(feature = "unstable-pre-spec")]

View File

@ -39,7 +39,7 @@ ruma_api! {
response: {
/// The MXC URI for the uploaded content.
pub content_uri: MxcUri,
pub content_uri: Box<MxcUri>,
/// The [BlurHash](https://blurha.sh) for the uploaded content.
///
@ -68,7 +68,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given MXC URI.
pub fn new(content_uri: MxcUri) -> Self {
pub fn new(content_uri: Box<MxcUri>) -> Self {
Self {
content_uri,
#[cfg(feature = "unstable-pre-spec")]

View File

@ -62,7 +62,7 @@ pub struct RoomMember {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
}
impl RoomMember {
@ -89,7 +89,7 @@ mod test {
display_name: Some(display_name),
avatar_url: Some(avatar_url),
} if display_name == "alice"
&& avatar_url.to_string() == "mxc://localhost/wefuiwegh8742w"
&& avatar_url == "mxc://localhost/wefuiwegh8742w"
);
#[cfg(feature = "compat")]

View File

@ -30,7 +30,7 @@ ruma_api! {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The [BlurHash](https://blurha.sh) for the avatar pointed to by `avatar_url`.
///
@ -53,7 +53,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given avatar URL.
pub fn new(avatar_url: Option<MxcUri>) -> Self {
pub fn new(avatar_url: Option<Box<MxcUri>>) -> Self {
Self {
avatar_url,
#[cfg(feature = "unstable-pre-spec")]

View File

@ -30,7 +30,7 @@ ruma_api! {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The user's display name, if set.
#[serde(skip_serializing_if = "Option::is_none")]
@ -57,7 +57,7 @@ impl<'a> Request<'a> {
impl Response {
/// Creates a new `Response` with the given avatar URL and display name.
pub fn new(avatar_url: Option<MxcUri>, displayname: Option<String>) -> Self {
pub fn new(avatar_url: Option<Box<MxcUri>>, displayname: Option<String>) -> Self {
Self {
avatar_url,
displayname,

View File

@ -474,7 +474,7 @@ pub struct UserProfile {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The user's display name, if set.
#[serde(skip_serializing_if = "Option::is_none")]

View File

@ -178,7 +178,7 @@ pub struct IdentityProvider {
name: String,
/// The icon for the provider.
icon: Option<MxcUri>,
icon: Option<Box<MxcUri>>,
/// The brand identifier for the provider.
brand: Option<IdentityProviderBrand>,
@ -337,7 +337,7 @@ mod tests {
brand: Some(IdentityProviderBrand::GitLab),
}) if id == "oidc-gitlab"
&& name == "GitLab"
&& icon.to_string() == "mxc://localhost/gitlab-icon"
&& icon == "mxc://localhost/gitlab-icon"
);
}

View File

@ -87,7 +87,7 @@ pub struct User {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
}
impl User {

View File

@ -58,7 +58,7 @@ pub struct PublicRoomsChunk {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
}
/// Initial set of mandatory fields of `PublicRoomsChunk`.

View File

@ -57,7 +57,6 @@ event_enum! {
"m.sticker",
}
/// Any state event.
enum State {
"m.policy.rule.room",

View File

@ -37,7 +37,7 @@ pub struct PresenceEventContent {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// Whether or not the user is currently active.
#[serde(skip_serializing_if = "Option::is_none")]
@ -92,7 +92,7 @@ mod tests {
fn serialization() {
let event = PresenceEvent {
content: PresenceEventContent {
avatar_url: Some(mxc_uri!("mxc://localhost/wefuiwegh8742w")),
avatar_url: Some(mxc_uri!("mxc://localhost/wefuiwegh8742w").to_owned()),
currently_active: Some(false),
displayname: None,
last_active_ago: Some(uint!(2_478_593)),
@ -143,7 +143,7 @@ mod tests {
status_msg: Some(status_msg),
},
sender,
} if avatar_url.to_string() == "mxc://localhost/wefuiwegh8742w"
} if avatar_url == "mxc://localhost/wefuiwegh8742w"
&& status_msg == "Making cupcakes"
&& sender == "@example:localhost"
&& last_active_ago == uint!(2_478_593)

View File

@ -56,7 +56,7 @@ pub struct ImageInfo {
///
/// Only present if the thumbnail is unencrypted.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail_url: Option<MxcUri>,
pub thumbnail_url: Option<Box<MxcUri>>,
/// Information on the encrypted thumbnail image.
///
@ -116,7 +116,7 @@ impl ThumbnailInfo {
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct EncryptedFile {
/// The URL to the file.
pub url: MxcUri,
pub url: Box<MxcUri>,
/// A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object.
pub key: JsonWebKey,
@ -143,7 +143,7 @@ pub struct EncryptedFile {
#[allow(clippy::exhaustive_structs)]
pub struct EncryptedFileInit {
/// The URL to the file.
pub url: MxcUri,
pub url: Box<MxcUri>,
/// A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object.
pub key: JsonWebKey,

View File

@ -25,13 +25,13 @@ pub struct RoomAvatarEventContent {
///
/// With the `unstable-pre-spec` feature, this field is optional.
#[cfg(not(feature = "unstable-pre-spec"))]
pub url: MxcUri,
pub url: Box<MxcUri>,
/// URL of the avatar image.
///
/// Without the `unstable-pre-spec` feature, this field is not optional.
#[cfg(feature = "unstable-pre-spec")]
pub url: Option<MxcUri>,
pub url: Option<Box<MxcUri>>,
}
impl RoomAvatarEventContent {
@ -39,7 +39,7 @@ impl RoomAvatarEventContent {
///
/// With the `unstable-pre-spec` feature, this method takes no parameters.
#[cfg(not(feature = "unstable-pre-spec"))]
pub fn new(url: MxcUri) -> Self {
pub fn new(url: Box<MxcUri>) -> Self {
Self { info: None, url }
}
@ -78,7 +78,7 @@ pub struct ImageInfo {
/// The URL to the thumbnail of the image.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail_url: Option<MxcUri>,
pub thumbnail_url: Option<Box<MxcUri>>,
/// The [BlurHash](https://blurha.sh) for this image.
///

View File

@ -49,7 +49,7 @@ pub struct RoomMemberEventContent {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The display name for this user, if any.
///
@ -489,7 +489,7 @@ mod tests {
state_key,
unsigned,
prev_content: None,
} if avatar_url.to_string() == "mxc://example.org/SEsfnsuifSDFSSEF"
} if avatar_url == "mxc://example.org/SEsfnsuifSDFSSEF"
&& displayname == "Alice Margatroid"
&& third_party_displayname == "alice"
&& mxid == "@alice:example.org"
@ -574,7 +574,7 @@ mod tests {
&& sender == "@alice:example.org"
&& state_key == "@alice:example.org"
&& unsigned.is_empty()
&& avatar_url.to_string() == "mxc://example.org/SEsfnsuifSDFSSEF"
&& avatar_url == "mxc://example.org/SEsfnsuifSDFSSEF"
&& displayname == "Alice Margatroid"
&& third_party_displayname == "alice"
&& mxid == "@alice:example.org"

View File

@ -403,7 +403,7 @@ pub struct AudioMessageEventContent {
///
/// Required if the file is unencrypted.
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<MxcUri>,
pub url: Option<Box<MxcUri>>,
/// Information on the encrypted audio clip.
///
@ -419,7 +419,7 @@ pub struct AudioMessageEventContent {
impl AudioMessageEventContent {
/// Creates a new non-encrypted `RoomAudioMessageEventContent` with the given body, url and
/// optional extra info.
pub fn plain(body: String, url: MxcUri, info: Option<Box<AudioInfo>>) -> Self {
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<AudioInfo>>) -> Self {
Self { body, url: Some(url), info, file: None }
}
@ -504,7 +504,7 @@ pub struct FileMessageEventContent {
/// The URL to the file.
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<MxcUri>,
pub url: Option<Box<MxcUri>>,
/// Information on the encrypted file.
///
@ -520,7 +520,7 @@ pub struct FileMessageEventContent {
impl FileMessageEventContent {
/// Creates a new non-encrypted `RoomFileMessageEventContent` with the given body, url and
/// optional extra info.
pub fn plain(body: String, url: MxcUri, info: Option<Box<FileInfo>>) -> Self {
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<FileInfo>>) -> Self {
Self { body, filename: None, url: Some(url), info, file: None }
}
@ -551,7 +551,7 @@ pub struct FileInfo {
///
/// Only present if the thumbnail is unencrypted.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail_url: Option<MxcUri>,
pub thumbnail_url: Option<Box<MxcUri>>,
/// Information on the encrypted thumbnail file.
///
@ -580,7 +580,7 @@ pub struct ImageMessageEventContent {
/// The URL to the image.
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<MxcUri>,
pub url: Option<Box<MxcUri>>,
/// Information on the encrypted image.
///
@ -596,7 +596,7 @@ pub struct ImageMessageEventContent {
impl ImageMessageEventContent {
/// Creates a new non-encrypted `RoomImageMessageEventContent` with the given body, url and
/// optional extra info.
pub fn plain(body: String, url: MxcUri, info: Option<Box<ImageInfo>>) -> Self {
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<ImageInfo>>) -> Self {
Self { body, url: Some(url), info, file: None }
}
@ -639,7 +639,7 @@ pub struct LocationInfo {
///
/// Only present if the thumbnail is unencrypted.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail_url: Option<MxcUri>,
pub thumbnail_url: Option<Box<MxcUri>>,
/// Information on an encrypted thumbnail of the location being represented.
///
@ -871,7 +871,7 @@ pub struct VideoMessageEventContent {
/// The URL to the video clip.
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<MxcUri>,
pub url: Option<Box<MxcUri>>,
/// Information on the encrypted video clip.
///
@ -887,7 +887,7 @@ pub struct VideoMessageEventContent {
impl VideoMessageEventContent {
/// Creates a new non-encrypted `RoomVideoMessageEventContent` with the given body, url and
/// optional extra info.
pub fn plain(body: String, url: MxcUri, info: Option<Box<VideoInfo>>) -> Self {
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<VideoInfo>>) -> Self {
Self { body, url: Some(url), info, file: None }
}
@ -930,7 +930,7 @@ pub struct VideoInfo {
///
/// Only present if the thumbnail is unencrypted.
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail_url: Option<MxcUri>,
pub thumbnail_url: Option<Box<MxcUri>>,
/// Information on the encrypted thumbnail file.
///

View File

@ -23,12 +23,12 @@ pub struct StickerEventContent {
pub info: ImageInfo,
/// The URL to the sticker image.
pub url: MxcUri,
pub url: Box<MxcUri>,
}
impl StickerEventContent {
/// Creates a new `StickerEventContent` with the given body, image info and URL.
pub fn new(body: String, info: ImageInfo, url: MxcUri) -> Self {
pub fn new(body: String, info: ImageInfo, url: Box<MxcUri>) -> Self {
Self { body, info, url }
}
}

View File

@ -82,9 +82,9 @@ fn serialize_message_event() {
mimetype: Some("image/png".into()),
size: UInt::new(82595),
}))),
thumbnail_url: Some(mxc_uri!("mxc://matrix.org/mnrsnsRRS787TSts")),
thumbnail_url: Some(mxc_uri!("mxc://matrix.org/mnrsnsRRS787TSts").to_owned()),
}),
mxc_uri!("mxc://matrix.org/arsrns98rsRSR"),
mxc_uri!("mxc://matrix.org/arsrns98rsRSR").to_owned(),
),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),

View File

@ -28,9 +28,9 @@ fn message_serialize_sticker() {
mimetype: Some("image/png".into()),
size: UInt::new(82595),
}))),
thumbnail_url: Some(mxc_uri!("mxc://matrix.org/irsns989Rrsn")),
thumbnail_url: Some(mxc_uri!("mxc://matrix.org/irsns989Rrsn").to_owned()),
}),
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs"),
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs").to_owned(),
),
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
@ -203,7 +203,7 @@ fn deserialize_message_sticker() {
&& width == UInt::new(1011)
&& mimetype == "image/png"
&& size == UInt::new(84242)
&& thumbnail_url.to_string() == "mxc://matrix.org/irnsNRS2879"
&& thumbnail_url == "mxc://matrix.org/irnsNRS2879"
&& matches!(
thumbnail_info.as_ref(),
ThumbnailInfo {
@ -217,7 +217,7 @@ fn deserialize_message_sticker() {
&& *thumb_mimetype == Some("image/png".into())
&& *thumb_size == UInt::new(82595)
)
&& url.to_string() == "mxc://matrix.org/jxPXTKpyydzdHJkdFNZjTZrD"
&& url == "mxc://matrix.org/jxPXTKpyydzdHJkdFNZjTZrD"
&& unsigned.is_empty()
);
}

View File

@ -37,7 +37,7 @@ fn serialization() {
let ev = RoomMessageEvent {
content: RoomMessageEventContent::new(MessageType::Audio(AudioMessageEventContent::plain(
"test".into(),
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd"),
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd").to_owned(),
None,
))),
event_id: event_id!("$143273582443PhrSn:example.org").to_owned(),
@ -69,7 +69,7 @@ fn content_serialization() {
let message_event_content =
RoomMessageEventContent::new(MessageType::Audio(AudioMessageEventContent::plain(
"test".into(),
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd"),
mxc_uri!("mxc://example.org/ffed755USFFxlgbQYZGtryd").to_owned(),
None,
)));
@ -380,7 +380,7 @@ fn content_deserialization() {
..
}),
..
} if body == "test" && url.to_string() == "mxc://example.org/ffed755USFFxlgbQYZGtryd"
} if body == "test" && url == "mxc://example.org/ffed755USFFxlgbQYZGtryd"
);
}

View File

@ -150,6 +150,7 @@ fn deserialize_aliases_sync_with_room_id() {
}
#[test]
#[allow(clippy::cmp_owned)] // seems buggy
fn deserialize_avatar_without_prev_content() {
let json_data = json!({
"content": {
@ -176,7 +177,7 @@ fn deserialize_avatar_without_prev_content() {
"type": "m.room.avatar"
});
let expected_url = "mxc://matrix.org/rnsldl8srs98IRrs".into();
let expected_url = mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs").to_owned();
#[cfg(feature = "unstable-pre-spec")]
let expected_url = Some(expected_url);
@ -227,7 +228,7 @@ fn deserialize_avatar_without_prev_content() {
&& *thumb_height == UInt::new(334)
&& *thumb_mimetype == Some("image/png".into())
&& *thumb_size == UInt::new(82595)
&& *thumbnail_url == mxc_uri!("mxc://matrix.org/98irRSS23srs")
&& thumbnail_url == mxc_uri!("mxc://matrix.org/98irRSS23srs")
)
)
&& url == expected_url

View File

@ -120,7 +120,7 @@ fn deserialize_stripped_state_events() {
let expected_url = mxc_uri!("mxc://example.com/iMag3");
#[cfg(feature = "unstable-pre-spec")]
let expected_url = Some(expected_url);
let expected_url = Some(expected_url.to_owned());
assert_eq!(image_info.height.unwrap(), uint!(128));
assert_eq!(image_info.width.unwrap(), uint!(128));

View File

@ -40,7 +40,7 @@ ruma_api! {
feature = "compat",
serde(default, deserialize_with = "ruma_serde::empty_string_as_none")
)]
pub avatar_url: Option<MxcUri>,
pub avatar_url: Option<Box<MxcUri>>,
/// The [BlurHash](https://blurha.sh) for the avatar pointed to by `avatar_url`.
///

View File

@ -117,9 +117,7 @@ pub fn mxc_uri(input: TokenStream) -> TokenStream {
assert!(mxc_uri::validate(&id.value()).is_ok(), "Invalid mxc://");
let output = quote! {
<#dollar_crate::MxcUri as ::std::convert::TryFrom<&str>>::try_from(
#id,
).unwrap()
<&#dollar_crate::MxcUri as ::std::convert::From<&str>>::from(#id)
};
output.into()

View File

@ -2,21 +2,22 @@
//!
//! [MXC URI]: https://matrix.org/docs/spec/client_server/r0.6.1#mxc-uri
use std::{convert::TryInto, fmt, num::NonZeroU8};
use std::{convert::TryInto, num::NonZeroU8};
use ruma_identifiers_validation::{error::MxcUriError, mxc_uri::validate};
use crate::ServerName;
type Result<T> = std::result::Result<T, MxcUriError>;
type Result<T, E = MxcUriError> = std::result::Result<T, E>;
/// A URI that should be a Matrix-spec compliant [MXC URI].
///
/// [MXC URI]: https://matrix.org/docs/spec/client_server/r0.6.1#mxc-uri
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MxcUri {
full_uri: Box<str>,
}
#[repr(transparent)]
pub struct MxcUri(str);
opaque_identifier!(MxcUri);
impl MxcUri {
/// If this is a valid MXC URI, returns the media ID.
@ -34,8 +35,8 @@ impl MxcUri {
pub fn parts(&self) -> Result<(&ServerName, &str)> {
self.extract_slash_idx().map(|idx| {
(
self.full_uri[6..idx.get() as usize].try_into().unwrap(),
&self.full_uri[idx.get() as usize + 1..],
self.as_str()[6..idx.get() as usize].try_into().unwrap(),
&self.as_str()[idx.get() as usize + 1..],
)
})
}
@ -51,12 +52,6 @@ impl MxcUri {
self.validate().is_ok()
}
/// Create a string slice from this MXC URI.
#[inline(always)]
pub fn as_str(&self) -> &str {
&self.full_uri
}
// convenience method for calling validate(self)
#[inline(always)]
fn extract_slash_idx(&self) -> Result<NonZeroU8> {
@ -64,57 +59,6 @@ impl MxcUri {
}
}
impl fmt::Debug for MxcUri {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.full_uri.fmt(f)
}
}
impl fmt::Display for MxcUri {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.full_uri.fmt(f)
}
}
fn from<S>(uri: S) -> MxcUri
where
S: AsRef<str> + Into<Box<str>>,
{
MxcUri { full_uri: uri.into() }
}
impl From<&str> for MxcUri {
fn from(s: &str) -> Self {
from(s)
}
}
impl From<String> for MxcUri {
fn from(s: String) -> Self {
from(s)
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for MxcUri {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
String::deserialize(deserializer).map(Into::into)
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for MxcUri {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[cfg(test)]
mod tests {
use std::convert::TryInto;
@ -125,7 +69,7 @@ mod tests {
#[test]
fn parse_mxc_uri() {
let mxc = MxcUri::from("mxc://127.0.0.1/asd32asdfasdsd");
let mxc = Box::<MxcUri>::from("mxc://127.0.0.1/asd32asdfasdsd");
assert!(mxc.is_valid());
assert_eq!(
@ -136,7 +80,7 @@ mod tests {
#[test]
fn parse_mxc_uri_without_media_id() {
let mxc = MxcUri::from("mxc://127.0.0.1");
let mxc = Box::<MxcUri>::from("mxc://127.0.0.1");
assert!(!mxc.is_valid());
assert_eq!(mxc.parts(), Err(MxcUriError::MissingSlash));
@ -144,14 +88,14 @@ mod tests {
#[test]
fn parse_mxc_uri_without_protocol() {
assert!(!MxcUri::from("127.0.0.1/asd32asdfasdsd").is_valid());
assert!(!Box::<MxcUri>::from("127.0.0.1/asd32asdfasdsd").is_valid());
}
#[cfg(feature = "serde")]
#[test]
fn serialize_mxc_uri() {
assert_eq!(
serde_json::to_string(&MxcUri::from("mxc://server/1234id"))
serde_json::to_string(&Box::<MxcUri>::from("mxc://server/1234id"))
.expect("Failed to convert MxcUri to JSON."),
r#""mxc://server/1234id""#
);
@ -160,7 +104,7 @@ mod tests {
#[cfg(feature = "serde")]
#[test]
fn deserialize_mxc_uri() {
let mxc = serde_json::from_str::<MxcUri>(r#""mxc://server/1234id""#)
let mxc = serde_json::from_str::<Box<MxcUri>>(r#""mxc://server/1234id""#)
.expect("Failed to convert JSON to MxcUri");
assert_eq!(mxc.as_str(), "mxc://server/1234id");

View File

@ -263,6 +263,7 @@ fn strip_lifetimes(field_type: &mut Type) -> bool {
|| last_seg.ident == "DeviceId"
|| last_seg.ident == "DeviceKeyId"
|| last_seg.ident == "EventId"
|| last_seg.ident == "MxcUri"
|| last_seg.ident == "ServerName"
|| last_seg.ident == "SessionId"
|| last_seg.ident == "RawJsonValue"