rusty_booru/safebooru/
mod.rs

1pub mod client;
2
3use derive_more::From;
4
5use serde::Deserialize;
6use strum::Display;
7
8use crate::{
9    generic::{BooruPost, Rating},
10    shared::client::ClientInformation,
11};
12
13use self::client::SafebooruClient;
14
15#[derive(Deserialize, Debug, Clone)]
16pub struct SafebooruPost {
17    pub id: u32,
18    pub score: Option<u32>,
19    /// This can be `null` for really recent posts
20    pub height: u32,
21    pub width: u32,
22    pub hash: String,
23    pub tags: String,
24    pub image: String,
25
26    /// The directory where the safebooru image file is stored at.
27    pub directory: String,
28
29    /// This is basically equivalent to `updated_at` in a Danbooru post. Except
30    /// that it's provided as a UNIX timestamp. Safebooru provides no `created_at`
31    /// field.
32    pub change: u32,
33    pub rating: SafebooruRating,
34}
35
36#[derive(Deserialize, Debug, Clone, Display, From)]
37#[serde(rename_all = "lowercase")]
38#[strum(serialize_all = "lowercase")]
39pub enum SafebooruRating {
40    Safe,
41    General,
42    // Yes there are explicit and questionable posts. Though you only need to care
43    // about them if you're querying for deleted content.
44    Questionable,
45    Explicit,
46}
47
48impl From<Rating> for SafebooruRating {
49    fn from(value: Rating) -> Self {
50        match value {
51            Rating::Explicit => SafebooruRating::Explicit,
52            Rating::Questionable => SafebooruRating::Questionable,
53            Rating::Safe => SafebooruRating::Safe,
54            Rating::Sensitive => SafebooruRating::Questionable,
55            Rating::General => SafebooruRating::General,
56        }
57    }
58}
59
60impl From<SafebooruRating> for Rating {
61    fn from(value: SafebooruRating) -> Self {
62        match value {
63            SafebooruRating::Safe => Rating::Safe,
64            SafebooruRating::General => Rating::General,
65            SafebooruRating::Questionable => Rating::Questionable,
66            SafebooruRating::Explicit => Rating::Explicit,
67        }
68    }
69}
70
71impl From<SafebooruPost> for BooruPost {
72    fn from(post: SafebooruPost) -> Self {
73        Self {
74            id: post.id,
75            created_at: None,
76            score: post.score.unwrap_or_default().into(),
77            width: post.width,
78            height: post.height,
79            md5: None,
80            file_url: format!(
81                "{}/images/{}/{}",
82                SafebooruClient::URL,
83                post.directory,
84                post.image
85            )
86            .into(),
87            tags: post.tags,
88            image: post.image.into(),
89            source: None,
90            rating: post.rating.into(),
91        }
92    }
93}