use iri_string::types::IriAbsoluteString;
use serde::{de::Error, Deserialize, Serialize};
use serde_json::Value;
use crate::models::media::MediaThumbnail;
pub mod bandcamp;
pub mod gfycat;
pub mod imgur;
pub mod kickstarter;
pub mod quora;
pub mod soundcloud;
pub mod spotify;
pub mod streamable;
pub mod twitch;
pub mod twitter;
pub mod vimeo;
pub mod vimeo_player;
pub mod youtube;
pub mod youtube_mobile;
#[derive(Debug, Clone, Serialize, PartialEq)]
pub enum OEmbed {
YouTube(OEmbedData<youtube::YouTube>),
YouTubeMobile(OEmbedData<youtube_mobile::YouTubeMobile>),
Streamable(OEmbedData<streamable::Streamable>),
Gfycat(OEmbedData<gfycat::Gfycat>),
Twitch(OEmbedData<twitch::Twitch>),
Twitter(OEmbedData<twitter::Twitter>),
Spotify(OEmbedData<spotify::Spotify>),
Imgur(OEmbedData<imgur::Imgur>),
Quora(OEmbedData<quora::Quora>),
SoundCloud(OEmbedData<soundcloud::SoundCloud>),
Vimeo(OEmbedData<vimeo::Vimeo>),
VimeoPlayer(OEmbedData<vimeo_player::VimeoPlayer>),
Kickstarter(OEmbedData<kickstarter::Kickstarter>),
Bandcamp(OEmbedData<bandcamp::Bandcamp>),
}
impl<'de> Deserialize<'de> for OEmbed {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct Proxy {
#[serde(rename = "type")]
ty: String,
oembed: Value,
}
let proxy = Proxy::deserialize(deserializer);
let proxy = match proxy {
Ok(proxy) => proxy,
Err(why) => return Err(why),
};
let oembed = match proxy
.ty
.split_terminator('.')
.collect::<Vec<_>>()
.as_slice()
{
["youtube", "com"] => {
OEmbed::YouTube(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["m", "youtube", "com"] => OEmbed::YouTubeMobile(
serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?,
),
["streamable", "com"] => {
OEmbed::Streamable(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["gfycat", "com"] => {
OEmbed::Gfycat(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["clips", "twitch", "tv"] => {
OEmbed::Twitch(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["twitter", "com"] => {
OEmbed::Twitter(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["open", "spotify", "com"] => {
OEmbed::Spotify(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["imgur", "com"] => {
OEmbed::Imgur(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["quora", "com"] => {
OEmbed::Quora(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["soundcloud", "com"] => {
OEmbed::SoundCloud(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["vimeo", "com"] => {
OEmbed::Vimeo(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["kickstarter", "com"] => {
OEmbed::Kickstarter(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
["player", "vimeo", "com"] => {
OEmbed::VimeoPlayer(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
[_, "bandcamp", "com"] => {
OEmbed::Bandcamp(serde_json::from_value(proxy.oembed).map_err(D::Error::custom)?)
}
_ => {
return Err(D::Error::invalid_value(
serde::de::Unexpected::Str(&proxy.ty),
&"one of theavailable oembed types",
))
}
};
Ok(oembed)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct OEmbedProvider {
#[serde(rename = "provider_name")]
pub name: String,
#[serde(rename = "provider_url")]
pub url: IriAbsoluteString,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct OEmbedData<T> {
pub version: OEmbedVersion,
#[serde(rename = "type")]
pub ty: OEmbedType,
#[serde(flatten)]
pub thumbnail: Option<MediaThumbnail>,
#[serde(flatten)]
pub provider: OEmbedProvider,
pub height: Option<u16>,
pub width: u16,
pub html: String,
#[serde(flatten)]
pub vendor_specific_data: T,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum OEmbedVersion {
#[serde(rename = "1.0")]
V1_0,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum OEmbedType {
Video,
Rich,
}