events: Add custom Deserialize impls for MediaSource
This commit is contained in:
parent
8afc3a1100
commit
deea762b8e
@ -5,7 +5,7 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de, Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
serde::{base64::UrlSafe, Base64},
|
serde::{base64::UrlSafe, Base64},
|
||||||
@ -34,7 +34,7 @@ pub mod tombstone;
|
|||||||
pub mod topic;
|
pub mod topic;
|
||||||
|
|
||||||
/// The source of a media file.
|
/// The source of a media file.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
#[allow(clippy::exhaustive_enums)]
|
#[allow(clippy::exhaustive_enums)]
|
||||||
pub enum MediaSource {
|
pub enum MediaSource {
|
||||||
/// The MXC URI to the unencrypted media file.
|
/// The MXC URI to the unencrypted media file.
|
||||||
@ -46,6 +46,30 @@ pub enum MediaSource {
|
|||||||
Encrypted(Box<EncryptedFile>),
|
Encrypted(Box<EncryptedFile>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Custom implementation of `Deserialize`, because serde doesn't guarantee what variant will be
|
||||||
|
/// deserialized for "externally tagged"¹ enums where multiple "tag" fields exist.
|
||||||
|
///
|
||||||
|
/// ¹ https://serde.rs/enum-representations.html
|
||||||
|
impl<'de> Deserialize<'de> for MediaSource {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct MediaSourceJsonRepr {
|
||||||
|
url: Option<Box<MxcUri>>,
|
||||||
|
file: Option<Box<EncryptedFile>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
match MediaSourceJsonRepr::deserialize(deserializer)? {
|
||||||
|
MediaSourceJsonRepr { url: None, file: None } => Err(de::Error::missing_field("url")),
|
||||||
|
// Prefer file if it is set
|
||||||
|
MediaSourceJsonRepr { file: Some(file), .. } => Ok(MediaSource::Encrypted(file)),
|
||||||
|
MediaSourceJsonRepr { url: Some(url), .. } => Ok(MediaSource::Plain(url)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Metadata about an image.
|
/// Metadata about an image.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
//! De-/serialization functions for `Option<MediaSource>` objects representing a thumbnail source.
|
//! De-/serialization functions for `Option<MediaSource>` objects representing a thumbnail source.
|
||||||
|
|
||||||
use serde::{
|
use serde::{
|
||||||
de::Deserializer,
|
|
||||||
ser::{SerializeStruct, Serializer},
|
ser::{SerializeStruct, Serializer},
|
||||||
Deserialize,
|
Deserialize, Deserializer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::MxcUri;
|
use crate::MxcUri;
|
||||||
@ -32,25 +31,20 @@ pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<MediaSource>, D::Er
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
Option::<ThumbnailSource>::deserialize(deserializer).map(|source| source.map(Into::into))
|
#[derive(Deserialize)]
|
||||||
}
|
pub struct ThumbnailSourceJsonRepr {
|
||||||
|
thumbnail_url: Option<Box<MxcUri>>,
|
||||||
|
thumbnail_file: Option<Box<EncryptedFile>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
match ThumbnailSourceJsonRepr::deserialize(deserializer)? {
|
||||||
enum ThumbnailSource {
|
ThumbnailSourceJsonRepr { thumbnail_url: None, thumbnail_file: None } => Ok(None),
|
||||||
/// The MXC URI to the unencrypted media file.
|
// Prefer file if it is set
|
||||||
#[serde(rename = "thumbnail_url")]
|
ThumbnailSourceJsonRepr { thumbnail_file: Some(file), .. } => {
|
||||||
Plain(Box<MxcUri>),
|
Ok(Some(MediaSource::Encrypted(file)))
|
||||||
|
}
|
||||||
/// The encryption info of the encrypted media file.
|
ThumbnailSourceJsonRepr { thumbnail_url: Some(url), .. } => {
|
||||||
#[serde(rename = "thumbnail_file")]
|
Ok(Some(MediaSource::Plain(url)))
|
||||||
Encrypted(Box<EncryptedFile>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ThumbnailSource> for MediaSource {
|
|
||||||
fn from(source: ThumbnailSource) -> Self {
|
|
||||||
match source {
|
|
||||||
ThumbnailSource::Plain(url) => Self::Plain(url),
|
|
||||||
ThumbnailSource::Encrypted(file) => Self::Encrypted(file),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user