imgurs_model/model/image.rs
1//! Image specification
2
3use serde::{Deserialize, Serialize};
4use time::{serde::timestamp, OffsetDateTime};
5use url::Url;
6
7/// The base model for an image.
8#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10#[serde(deny_unknown_fields)]
11pub struct Image {
12 /// Is the image animated
13 pub animated: bool,
14 /// Bandwidth consumed by the image in bytes
15 pub bandwidth: u64,
16 /// Time uploaded, epoch time
17 #[serde(with = "timestamp")]
18 pub datetime: OffsetDateTime,
19 /// OPTIONAL, the deletehash, if you're logged in as the image owner
20 pub deletehash: Option<String>,
21 /// Description of the image.
22 pub description: Option<String>,
23 /// Indicates if the current user favorited the image. Defaults to false if not signed in.
24 pub favorite: Option<bool>,
25 /// OPTIONAL, The .gifv link. Only available if the image is animated and type is 'image/gif'.
26 pub gifv: Option<Url>,
27 /// The height of the image in pixels
28 pub height: u64,
29 /// The ID for the image
30 pub id: String,
31 /// True if the image has been submitted to the gallery, false if otherwise.
32 pub is_gallery: Option<bool>,
33 /// The direct link to the the image. (Note: if fetching an animated GIF that was over 20MB in original size, a .gif thumbnail will be returned)
34 pub link: Option<Url>,
35 /// OPTIONAL, Whether the image has a looping animation. Only available if the image is animated and type is 'image/gif'.
36 pub looping: Option<bool>,
37 /// Image MIME type.
38 #[serde(rename = "type")]
39 pub mime_type: String,
40 /// OPTIONAL, The direct link to the .mp4. Only available if the image is animated and type is 'image/gif'.
41 pub mp4: Option<Url>,
42 /// OPTIONAL, The Content-Length of the .mp4. Only available if the image is animated and type is 'image/gif'. Note that a zero value (0) is possible if the video has not yet been generated
43 pub mp4_size: Option<u64>,
44 /// Indicates if the image has been marked as nsfw or not. Defaults to null if information is not available.
45 /// OPTIONAL, the original filename, if you're logged in as the image owner
46 pub name: Option<String>,
47 /// Whether the content is NSFW
48 pub nsfw: Option<bool>,
49 /// If the image has been categorized by our backend then this will contain the section the image belongs in. (funny, cats, adviceanimals, wtf, etc)
50 pub section: Option<String>,
51 /// The size of the image in bytes
52 pub size: u64,
53 /// The title of the image.
54 pub title: Option<String>,
55 /// The number of image views
56 pub views: u64,
57 /// The current user's vote on the album. null if not signed in or if the user hasn't voted on it.
58 pub vote: Option<String>,
59 /// The width of the image in pixels
60 pub width: u64,
61}
62
63#[cfg(test)]
64mod test {
65 use std::error::Error;
66
67 use crate::model::basic::Basic;
68 use crate::model::gallery_image::GalleryImage;
69
70 #[test]
71 fn test_deserialize_gallery_image_local() -> Result<(), Box<dyn Error>> {
72 let res = r#"{
73 "data": {
74 "id": "OUHDm",
75 "title": "My most recent drawing. Spent over 100 hours. I'm pretty proud of it.",
76 "description": null,
77 "datetime": 1349051625,
78 "type": "image/jpeg",
79 "animated": false,
80 "width": 2490,
81 "height": 3025,
82 "size": 618969,
83 "views": 625622,
84 "comment_count": 10,
85 "bandwidth": 387240623718,
86 "vote": null,
87 "section": "pics",
88 "account_url": "saponifi3d",
89 "account_id": 384077,
90 "ups": 1889,
91 "downs": 58,
92 "points": 1831,
93 "score": 18935622,
94 "is_album": false
95 },
96 "success" : true,
97 "status" : 200
98 }"#;
99
100 let data = serde_json::from_str::<Basic<GalleryImage>>(res)?;
101
102 println!("{:#?}", data);
103
104 Ok(())
105 }
106}