oembed_rs/
spec.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// An oEmbed provider
7///
8/// See the [oembed spec](https://oembed.com/#section7.1) for more information
9#[derive(Debug, Deserialize)]
10pub struct Provider {
11    pub provider_name: String,
12    pub provider_url: String,
13    pub endpoints: Vec<Endpoint>,
14}
15
16/// An oEmbed provider endpoint
17#[derive(Debug, Deserialize)]
18pub struct Endpoint {
19    #[serde(default)]
20    pub schemes: Vec<String>,
21    pub url: String,
22    #[serde(default)]
23    pub discovery: bool,
24}
25
26/// Represents one of the oEmbed data types
27#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
28#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
29#[serde(tag = "type")]
30pub enum EmbedType {
31    /// Photo type
32    ///
33    /// See section 2.3.4.1. of the [oembed spec](https://oembed.com) for more information
34    #[serde(rename = "photo")]
35    Photo(Photo),
36    /// Video type
37    ///
38    /// See section 2.3.4.2. of the [oembed spec](https://oembed.com) for more information
39    #[serde(rename = "video")]
40    Video(Video),
41    /// Link type
42    ///
43    /// See section 2.3.4.3. of the [oembed spec](https://oembed.com) for more information
44    #[serde(rename = "link")]
45    Link,
46    /// Rich type
47    ///
48    /// See section 2.3.4.4. of the [oembed spec](https://oembed.com) for more information
49    #[serde(rename = "rich")]
50    Rich(Rich),
51}
52
53/// Video type
54///
55/// See section 2.3.4.2. of the [oembed spec](https://oembed.com) for more information
56#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
57#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
58pub struct Video {
59    pub html: String,
60    pub width: Option<i32>,
61    pub height: Option<i32>,
62}
63
64/// Photo type
65///
66/// See section 2.3.4.1. of the [oembed spec](https://oembed.com) for more information
67#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
68#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
69pub struct Photo {
70    pub url: String,
71    pub width: Option<i32>,
72    pub height: Option<i32>,
73}
74
75/// Rich type
76///
77/// See section 2.3.4.4. of the [oembed spec](https://oembed.com) for more information
78#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
79#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
80pub struct Rich {
81    pub html: String,
82    pub width: Option<i32>,
83    pub height: Option<i32>,
84}
85
86/// oEmbed response
87///
88/// See the [oembed spec](https://oembed.com/#section2.3) for more information
89#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
90#[derive(Debug, Serialize, Deserialize, PartialEq)]
91pub struct EmbedResponse {
92    #[serde(flatten)]
93    pub oembed_type: EmbedType,
94    pub version: String,
95    pub title: Option<String>,
96    pub author_name: Option<String>,
97    pub author_url: Option<String>,
98    pub provider_name: Option<String>,
99    pub provider_url: Option<String>,
100    pub cache_age: Option<String>,
101    pub thumbnail_url: Option<String>,
102    pub thumbnail_width: Option<i32>,
103    pub thumbnail_height: Option<i32>,
104    #[serde(flatten)]
105    pub extra: HashMap<String, Value>,
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn test_photo() {
114        let input = r#"{
115            "type": "photo",
116            "version": "1.0",
117            "title": "photo",
118            "width": 100,
119            "height": 50,
120            "url": "https://example.com/photo.jpg"
121        }"#;
122        let response: EmbedResponse = serde_json::from_str(input).unwrap();
123
124        assert_eq!(response.title, Some("photo".to_string()));
125        assert_eq!(
126            response.oembed_type,
127            EmbedType::Photo(Photo {
128                url: "https://example.com/photo.jpg".to_string(),
129                width: Some(100),
130                height: Some(50)
131            })
132        )
133    }
134}