oembed/
lib.rs

1//! This crate provides a simple generic implementation of the [oEmbed
2//! specification][1] version 1.0.
3//!
4//! ## Notes and Caveats
5//!
6//! * No HTTP client mechanism is included; users of this library must provide an
7//!   implementation of [`client::Http`] to functions requiring remote resources.
8//! * [Discovery](https://oembed.com/#section4) is not currently supported.
9//! * XML responses are not currently supported.
10//! * *Some endpoints* — not naming names — will return data that doesn't conform with the
11//!   specification; such data can't currently be parsed by this library. No decision
12//!   on how to address this has been made yet, and suggestions are welcome.
13//!
14//! # Examples
15//!
16//! ```
17//! use std::error::Error;
18//! use std::borrow::Cow;
19//! use oembed::client::*;
20//!
21//! struct DummyHttp;
22//!
23//! impl Http for DummyHttp {
24//!     fn url_encode<'a>(&mut self, s: &'a str) -> HttpResult<Cow<'a, str>> {
25//!         Ok(s.into())
26//!     }
27//!
28//!     fn get(&mut self, _url: &str) -> HttpResult<String> {
29//!         Ok("{
30//!             \"version\": \"1.0\",
31//!             \"type\": \"photo\",
32//!             \"width\": 240,
33//!             \"height\": 160,
34//!             \"title\": \"ZB8T0193\",
35//!             \"url\": \"http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg\",
36//!             \"author_name\": \"Bees\",
37//!             \"author_url\": \"http://www.flickr.com/photos/bees/\",
38//!             \"provider_name\": \"Flickr\",
39//!             \"provider_url\": \"http://www.flickr.com/\"
40//!         }".to_string())
41//!     }
42//! }
43//!
44//! let schema = Schema::load_included();
45//! let some_url = "http://www.flickr.com/photos/bees/2341623661/";
46//! let mut http = DummyHttp {};
47//!
48//! let response = schema.fetch(&mut http, some_url)
49//!     .expect("Missing provider")
50//!     .expect("Failed to fetch server response");
51//!
52//! assert_eq!("ZB8T0193", response.title.unwrap());
53//! ```
54//!
55//! [1]: https://oembed.com/
56
57#[macro_use]
58extern crate serde;
59extern crate serde_json;
60
61pub mod client;
62
63/// Crate-wide error type
64#[derive(Debug)]
65pub enum Error {
66    /// Returned if [`client::Http::url_encode`] failed.
67    HttpUrlEncode(Box<dyn std::error::Error>),
68
69    /// Returned if [`client::Http::get`] failed.
70    HttpGet(Box<dyn std::error::Error>),
71
72    /// Returned if parsing a response failed.
73    ParseError(serde_json::Error),
74}
75
76impl std::fmt::Display for Error {
77    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
78        write!(f, "{:?}", self)
79    }
80}
81
82type Result<T> = std::result::Result<T, Error>;
83
84/// oEmbed provider
85#[derive(Deserialize, Serialize, Clone, PartialEq, PartialOrd, Hash, Debug, Default)]
86pub struct Provider {
87    #[serde(rename = "provider_name")]
88    pub name: String,
89
90    #[serde(rename = "provider_url")]
91    pub url: String,
92
93    pub endpoints: Vec<Endpoint>,
94}
95
96/// oEmbed endpoint
97#[derive(Deserialize, Serialize, Clone, PartialEq, PartialOrd, Hash, Debug, Default)]
98pub struct Endpoint {
99    pub url: String,
100    pub schemes: Option<Vec<String>>,
101    pub formats: Option<Vec<String>>,
102
103    /// Not currently supported
104    pub discovery: Option<bool>,
105}
106
107/// Endpoint response to an oEmbed request
108///
109/// See section 2.3.4 of the [oEmbed specification][1].
110///
111/// [1]: https://oembed.com/
112#[derive(Deserialize, Serialize, Clone, PartialEq, PartialOrd, Hash, Debug)]
113pub struct Response {
114    #[serde(flatten, rename(deserialize = "type"))]
115    pub response_type: ResponseType,
116    pub version: String,
117    pub title: Option<String>,
118    pub author_name: Option<String>,
119    pub author_url: Option<String>,
120    pub provider_name: Option<String>,
121    pub provider_url: Option<String>,
122    pub cache_age: Option<String>,
123    pub thumbnail_url: Option<String>,
124    pub thumbnail_width: Option<i32>,
125    pub thumbnail_height: Option<i32>,
126}
127
128/// Type-specific oEmbed response data
129///
130/// See section 2.3.4 of the [oEmbed specification][1].
131///
132/// [1]: https://oembed.com/
133#[derive(Deserialize, Serialize, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
134#[serde(tag = "type", rename_all(deserialize = "lowercase"))]
135pub enum ResponseType {
136    Photo {
137        url: String,
138        width: Option<i32>,
139        height: Option<i32>,
140    },
141
142    Video {
143        html: String,
144        width: Option<i32>,
145        height: Option<i32>,
146    },
147
148    Rich {
149        html: String,
150        width: Option<i32>,
151        height: Option<i32>,
152    },
153
154    Link,
155}