deviantart/types/
deviation.rs1use super::GetFullviewUrlError;
2use super::GetFullviewUrlOptions;
3use super::Media;
4use std::{collections::HashMap, path::Path};
5use url::Url;
6
7#[derive(Debug, serde::Deserialize)]
9pub struct Deviation {
10 #[serde(rename = "blockReasons")]
15 pub block_reasons: Vec<serde_json::Value>,
16
17 #[serde(rename = "deviationId")]
19 pub deviation_id: u64,
20
21 #[serde(rename = "type")]
23 pub kind: String,
24
25 pub url: Url,
27
28 pub media: Media,
30
31 pub title: String,
33
34 #[serde(rename = "textContent")]
36 pub text_content: Option<TextContext>,
37
38 #[serde(rename = "isDownloadable")]
40 pub is_downloadable: bool,
41
42 #[serde(flatten)]
44 pub unknown: HashMap<String, serde_json::Value>,
45}
46
47impl Deviation {
48 pub fn get_media_url(&self) -> Option<Url> {
50 let mut url = self.media.base_uri.as_ref()?.clone();
51 url.query_pairs_mut()
52 .append_pair("token", self.media.token.first()?);
53 Some(url)
54 }
55
56 pub fn get_download_url(&self) -> Option<Url> {
58 let mut url = self.media.base_uri.as_ref()?.clone();
59 url.query_pairs_mut()
60 .append_pair("token", self.media.token.get(1)?);
61 Some(url)
62 }
63
64 pub fn get_fullview_url(
66 &self,
67 options: GetFullviewUrlOptions,
68 ) -> Result<Url, GetFullviewUrlError> {
69 self.media.get_fullview_url(options)
70 }
71
72 pub fn get_gif_url(&self) -> Option<Url> {
74 let mut url = self.media.get_gif_media_type()?.b.clone()?;
75 url.query_pairs_mut()
76 .append_pair("token", self.media.token.first()?);
77 Some(url)
78 }
79
80 pub fn get_best_video_url(&self) -> Option<&Url> {
82 let url = self.media.get_best_video_media_type()?.b.as_ref()?;
83 Some(url)
84 }
85
86 pub fn is_image(&self) -> bool {
88 self.kind == "image"
89 }
90
91 pub fn is_literature(&self) -> bool {
93 self.kind == "literature"
94 }
95
96 pub fn is_film(&self) -> bool {
98 self.kind == "film"
99 }
100
101 pub fn get_image_download_url(&self) -> Option<Url> {
105 if let Some(url) = self.get_download_url() {
107 return Some(url);
108 }
109
110 if let Some(url) = self.get_gif_url() {
112 return Some(url);
113 }
114
115 None
117 }
118 pub fn get_extension(&self) -> Option<&str> {
120 if self.is_image() {
121 let url = self
122 .media
123 .get_gif_media_type()
124 .and_then(|media_type| media_type.b.as_ref())
125 .or(self.media.base_uri.as_ref())?;
126 Path::new(url.as_str()).extension()?.to_str()
127 } else if self.is_literature() {
128 None
129 } else if self.is_film() {
130 let url = self.media.get_best_video_media_type()?.b.as_ref()?;
131 Path::new(url.as_str()).extension()?.to_str()
132 } else {
133 None
134 }
135 }
136}
137
138#[derive(Debug, serde::Deserialize)]
139pub struct Author {
140 #[serde(rename = "isNewDeviant")]
142 pub is_new_deviant: bool,
143
144 #[serde(rename = "useridUuid")]
146 pub userid_uuid: String,
147
148 pub usericon: Url,
150
151 #[serde(rename = "userId")]
153 pub user_id: u64,
154
155 pub username: String,
157
158 #[serde(flatten)]
160 pub unknown: HashMap<String, serde_json::Value>,
161}
162
163#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
165pub struct TextContext {
166 pub excerpt: String,
168
169 pub html: Html,
171
172 #[serde(flatten)]
174 pub unknown: HashMap<String, serde_json::Value>,
175}
176
177#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
179pub struct Html {
180 pub features: String,
182
183 pub markup: Option<String>,
185
186 #[serde(rename = "type")]
188 pub kind: String,
189
190 #[serde(flatten)]
192 pub unknown: HashMap<String, serde_json::Value>,
193}
194
195impl Html {
196 pub fn get_markup(&self) -> Option<Result<Markup, serde_json::Error>> {
198 let markup = self.markup.as_ref()?;
199 Some(serde_json::from_str(markup))
200 }
201}
202
203#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
205pub struct Markup {
206 pub version: u32,
207 pub document: MarkupDocument,
208}
209
210#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
211pub struct MarkupDocument {
212 pub content: Vec<MarkupDocumentContent>,
213
214 #[serde(rename = "type")]
215 pub kind: String,
216}
217
218#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
219pub struct MarkupDocumentContent {
220 #[serde(rename = "type")]
221 pub kind: String,
222 pub attrs: HashMap<String, serde_json::Value>,
225
226 pub content: Option<Vec<MarkupDocumentContentInner>>,
227}
228
229#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
231pub struct MarkupDocumentContentInner {
232 #[serde(rename = "type")]
233 pub kind: String,
234 pub text: Option<String>,
236}