deviantart/types/
deviation.rs1use super::Media;
2use std::{collections::HashMap, path::Path};
3use url::Url;
4
5#[derive(Debug, serde::Deserialize)]
7pub struct Deviation {
8 #[serde(rename = "blockReasons")]
13 pub block_reasons: Vec<serde_json::Value>,
14
15 #[serde(rename = "deviationId")]
17 pub deviation_id: u64,
18
19 #[serde(rename = "type")]
21 pub kind: String,
22
23 pub url: Url,
25
26 pub media: Media,
28
29 pub title: String,
31
32 #[serde(rename = "textContent")]
34 pub text_content: Option<TextContext>,
35
36 #[serde(rename = "isDownloadable")]
38 pub is_downloadable: bool,
39
40 #[serde(flatten)]
42 pub unknown: HashMap<String, serde_json::Value>,
43}
44
45impl Deviation {
46 pub fn get_media_url(&self) -> Option<Url> {
48 let mut url = self.media.base_uri.as_ref()?.clone();
49 url.query_pairs_mut()
50 .append_pair("token", self.media.token.first()?);
51 Some(url)
52 }
53
54 pub fn get_download_url(&self) -> Option<Url> {
56 let mut url = self.media.base_uri.as_ref()?.clone();
57 url.query_pairs_mut()
58 .append_pair("token", self.media.token.get(1)?);
59 Some(url)
60 }
61
62 pub fn get_fullview_url(&self) -> Option<Url> {
64 self.media.get_fullview_url()
65 }
66
67 pub fn get_gif_url(&self) -> Option<Url> {
69 let mut url = self.media.get_gif_media_type()?.b.clone()?;
70 url.query_pairs_mut()
71 .append_pair("token", self.media.token.first()?);
72 Some(url)
73 }
74
75 pub fn get_best_video_url(&self) -> Option<&Url> {
77 let url = self.media.get_best_video_media_type()?.b.as_ref()?;
78 Some(url)
79 }
80
81 pub fn is_image(&self) -> bool {
83 self.kind == "image"
84 }
85
86 pub fn is_literature(&self) -> bool {
88 self.kind == "literature"
89 }
90
91 pub fn is_film(&self) -> bool {
93 self.kind == "film"
94 }
95
96 pub fn get_image_download_url(&self) -> Option<Url> {
100 if let Some(url) = self.get_download_url() {
102 return Some(url);
103 }
104
105 if let Some(url) = self.get_gif_url() {
107 return Some(url);
108 }
109
110 None
112 }
113 pub fn get_extension(&self) -> Option<&str> {
115 if self.is_image() {
116 let url = self
117 .media
118 .get_gif_media_type()
119 .and_then(|media_type| media_type.b.as_ref())
120 .or(self.media.base_uri.as_ref())?;
121 Path::new(url.as_str()).extension()?.to_str()
122 } else if self.is_literature() {
123 None
124 } else if self.is_film() {
125 let url = self.media.get_best_video_media_type()?.b.as_ref()?;
126 Path::new(url.as_str()).extension()?.to_str()
127 } else {
128 None
129 }
130 }
131}
132
133#[derive(Debug, serde::Deserialize)]
134pub struct Author {
135 #[serde(rename = "isNewDeviant")]
137 pub is_new_deviant: bool,
138
139 #[serde(rename = "useridUuid")]
141 pub userid_uuid: String,
142
143 pub usericon: Url,
145
146 #[serde(rename = "userId")]
148 pub user_id: u64,
149
150 pub username: String,
152
153 #[serde(flatten)]
155 pub unknown: HashMap<String, serde_json::Value>,
156}
157
158#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
160pub struct TextContext {
161 pub excerpt: String,
163
164 pub html: Html,
166
167 #[serde(flatten)]
169 pub unknown: HashMap<String, serde_json::Value>,
170}
171
172#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
174pub struct Html {
175 pub features: String,
177
178 pub markup: Option<String>,
180
181 #[serde(rename = "type")]
183 pub kind: String,
184
185 #[serde(flatten)]
187 pub unknown: HashMap<String, serde_json::Value>,
188}
189
190impl Html {
191 pub fn get_markup(&self) -> Option<Result<Markup, serde_json::Error>> {
193 let markup = self.markup.as_ref()?;
194 Some(serde_json::from_str(markup))
195 }
196}
197
198#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
200pub struct Markup {
201 pub version: u32,
202 pub document: MarkupDocument,
203}
204
205#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
206pub struct MarkupDocument {
207 pub content: Vec<MarkupDocumentContent>,
208
209 #[serde(rename = "type")]
210 pub kind: String,
211}
212
213#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
214pub struct MarkupDocumentContent {
215 #[serde(rename = "type")]
216 pub kind: String,
217 pub attrs: HashMap<String, serde_json::Value>,
220
221 pub content: Option<Vec<MarkupDocumentContentInner>>,
222}
223
224#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
226pub struct MarkupDocumentContentInner {
227 #[serde(rename = "type")]
228 pub kind: String,
229 pub text: Option<String>,
231}