216 lines
6.0 KiB
Rust
216 lines
6.0 KiB
Rust
//! Common types for [media content](https://matrix.org/docs/spec/client_server/r0.6.1#id66).
|
|
|
|
use ruma::{
|
|
api::client::r0::media::get_content_thumbnail::Method,
|
|
events::{
|
|
room::{
|
|
message::{
|
|
AudioMessageEventContent, FileMessageEventContent, ImageMessageEventContent,
|
|
LocationMessageEventContent, VideoMessageEventContent,
|
|
},
|
|
EncryptedFile,
|
|
},
|
|
sticker::StickerEventContent,
|
|
},
|
|
MxcUri, UInt,
|
|
};
|
|
|
|
const UNIQUE_SEPARATOR: &str = "_";
|
|
|
|
/// A trait to uniquely identify values of the same type.
|
|
pub trait UniqueKey {
|
|
/// A string that uniquely identifies `Self` compared to other values of
|
|
/// the same type.
|
|
fn unique_key(&self) -> String;
|
|
}
|
|
|
|
/// The requested format of a media file.
|
|
#[derive(Clone, Debug)]
|
|
pub enum MediaFormat {
|
|
/// The file that was uploaded.
|
|
File,
|
|
|
|
/// A thumbnail of the file that was uploaded.
|
|
Thumbnail(MediaThumbnailSize),
|
|
}
|
|
|
|
impl UniqueKey for MediaFormat {
|
|
fn unique_key(&self) -> String {
|
|
match self {
|
|
Self::File => "file".into(),
|
|
Self::Thumbnail(size) => size.unique_key(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The requested size of a media thumbnail.
|
|
#[derive(Clone, Debug)]
|
|
pub struct MediaThumbnailSize {
|
|
/// The desired resizing method.
|
|
pub method: Method,
|
|
|
|
/// The desired width of the thumbnail. The actual thumbnail may not match
|
|
/// the size specified.
|
|
pub width: UInt,
|
|
|
|
/// The desired height of the thumbnail. The actual thumbnail may not match
|
|
/// the size specified.
|
|
pub height: UInt,
|
|
}
|
|
|
|
impl UniqueKey for MediaThumbnailSize {
|
|
fn unique_key(&self) -> String {
|
|
format!("{}{}{}x{}", self.method, UNIQUE_SEPARATOR, self.width, self.height)
|
|
}
|
|
}
|
|
|
|
/// A request for media data.
|
|
#[derive(Clone, Debug)]
|
|
pub enum MediaType {
|
|
/// A media content URI.
|
|
Uri(MxcUri),
|
|
|
|
/// An encrypted media content.
|
|
Encrypted(Box<EncryptedFile>),
|
|
}
|
|
|
|
impl UniqueKey for MediaType {
|
|
fn unique_key(&self) -> String {
|
|
match self {
|
|
Self::Uri(uri) => uri.to_string(),
|
|
Self::Encrypted(file) => file.url.to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A request for media data.
|
|
#[derive(Clone, Debug)]
|
|
pub struct MediaRequest {
|
|
/// The type of the media file.
|
|
pub media_type: MediaType,
|
|
|
|
/// The requested format of the media data.
|
|
pub format: MediaFormat,
|
|
}
|
|
|
|
impl UniqueKey for MediaRequest {
|
|
fn unique_key(&self) -> String {
|
|
format!("{}{}{}", self.media_type.unique_key(), UNIQUE_SEPARATOR, self.format.unique_key())
|
|
}
|
|
}
|
|
|
|
/// Trait for media event content.
|
|
pub trait MediaEventContent {
|
|
/// Get the type of the file for `Self`.
|
|
///
|
|
/// Returns `None` if `Self` has no file.
|
|
fn file(&self) -> Option<MediaType>;
|
|
|
|
/// Get the type of the thumbnail for `Self`.
|
|
///
|
|
/// Returns `None` if `Self` has no thumbnail.
|
|
fn thumbnail(&self) -> Option<MediaType>;
|
|
}
|
|
|
|
impl MediaEventContent for StickerEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
Some(MediaType::Uri(self.url.clone()))
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
None
|
|
}
|
|
}
|
|
|
|
impl MediaEventContent for AudioMessageEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
self.url
|
|
.as_ref()
|
|
.map(|uri| MediaType::Uri(uri.clone()))
|
|
.or_else(|| self.file.as_ref().map(|e| MediaType::Encrypted(e.clone())))
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
None
|
|
}
|
|
}
|
|
|
|
impl MediaEventContent for FileMessageEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
self.url
|
|
.as_ref()
|
|
.map(|uri| MediaType::Uri(uri.clone()))
|
|
.or_else(|| self.file.as_ref().map(|e| MediaType::Encrypted(e.clone())))
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
self.info.as_ref().and_then(|info| {
|
|
if let Some(uri) = info.thumbnail_url.as_ref() {
|
|
Some(MediaType::Uri(uri.clone()))
|
|
} else {
|
|
info.thumbnail_file.as_ref().map(|file| MediaType::Encrypted(file.clone()))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
impl MediaEventContent for ImageMessageEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
self.url
|
|
.as_ref()
|
|
.map(|uri| MediaType::Uri(uri.clone()))
|
|
.or_else(|| self.file.as_ref().map(|e| MediaType::Encrypted(e.clone())))
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
self.info
|
|
.as_ref()
|
|
.and_then(|info| {
|
|
if let Some(uri) = info.thumbnail_url.as_ref() {
|
|
Some(MediaType::Uri(uri.clone()))
|
|
} else {
|
|
info.thumbnail_file.as_ref().map(|file| MediaType::Encrypted(file.clone()))
|
|
}
|
|
})
|
|
.or_else(|| self.url.as_ref().map(|uri| MediaType::Uri(uri.clone())))
|
|
}
|
|
}
|
|
|
|
impl MediaEventContent for VideoMessageEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
self.url
|
|
.as_ref()
|
|
.map(|uri| MediaType::Uri(uri.clone()))
|
|
.or_else(|| self.file.as_ref().map(|e| MediaType::Encrypted(e.clone())))
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
self.info
|
|
.as_ref()
|
|
.and_then(|info| {
|
|
if let Some(uri) = info.thumbnail_url.as_ref() {
|
|
Some(MediaType::Uri(uri.clone()))
|
|
} else {
|
|
info.thumbnail_file.as_ref().map(|file| MediaType::Encrypted(file.clone()))
|
|
}
|
|
})
|
|
.or_else(|| self.url.as_ref().map(|uri| MediaType::Uri(uri.clone())))
|
|
}
|
|
}
|
|
|
|
impl MediaEventContent for LocationMessageEventContent {
|
|
fn file(&self) -> Option<MediaType> {
|
|
None
|
|
}
|
|
|
|
fn thumbnail(&self) -> Option<MediaType> {
|
|
self.info.as_ref().and_then(|info| {
|
|
if let Some(uri) = info.thumbnail_url.as_ref() {
|
|
Some(MediaType::Uri(uri.clone()))
|
|
} else {
|
|
info.thumbnail_file.as_ref().map(|file| MediaType::Encrypted(file.clone()))
|
|
}
|
|
})
|
|
}
|
|
}
|