reddit_rs/models/
author.rs1use serde::{
2 de::{Error, Unexpected},
3 Deserialize, Serialize,
4};
5use uuid::Uuid;
6
7use crate::models::{
8 color::Color,
9 flair::{FlairTextColor, FlairType},
10 fullname::FullName,
11 richtext::Richtext,
12};
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15pub struct Author {
16 #[serde(flatten)]
17 pub author_info: AuthorInfo,
18 #[serde(rename = "author_is_blocked")]
19 pub is_blocked: bool,
20 #[serde(flatten)]
21 pub flair: AuthorFlair,
22}
23
24#[derive(Debug, Clone, Serialize, PartialEq)]
25pub enum AuthorInfo {
26 Deleted,
27 Author {
28 #[serde(rename = "author")]
29 name: String,
30 #[serde(rename = "author_fullname")]
31 fullname: FullName,
32 #[serde(rename = "author_premium")]
33 premium: bool,
34 #[serde(rename = "author_patreon_flair")]
35 patreon_flair: bool,
36 },
37}
38
39impl<'de> Deserialize<'de> for AuthorInfo {
40 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41 where
42 D: serde::Deserializer<'de>,
43 {
44 #[derive(Debug, Deserialize)]
45 struct RawAuthorInfo {
46 #[serde(rename = "author")]
47 name: String,
48 #[serde(rename = "author_fullname")]
49 fullname: Option<FullName>,
50 #[serde(rename = "author_premium")]
51 premium: Option<bool>,
52 #[serde(rename = "author_patreon_flair")]
53 patreon_flair: Option<bool>,
54 }
55
56 let info: RawAuthorInfo =
57 serde_json::from_value(serde_json::Value::deserialize(deserializer)?)
58 .map_err(D::Error::custom)?;
59
60 match info {
61 RawAuthorInfo {
62 name,
63 fullname: None,
64 premium: None,
65 patreon_flair: None,
66 } if name == "[deleted]" => Ok(AuthorInfo::Deleted),
67 RawAuthorInfo { name, .. } if name == "[deleted]" => Err(D::Error::invalid_value(
68 Unexpected::Other(
69 "[deleted] requires that all other author info fields are either null or not present",
70 ),
71 &"[deleted] requires that all other author info fields are either null or not present",
72 )),
73 RawAuthorInfo {
74 name,
75 fullname: Some(fullname),
76 premium: Some(premium),
77 patreon_flair: Some(patreon_flair),
78 } => Ok(AuthorInfo::Author {
79 name,
80 fullname,
81 patreon_flair,
82 premium,
83 }),
84 _ => Err(D::Error::invalid_value(
85 Unexpected::Other(
86 "author with name requires that all other author info fields are present",
87 ),
88 &"author with name requires that all other author info fields are present",
89 )),
90 }
91 }
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
95pub struct AuthorFlair {
96 #[serde(deserialize_with = "Color::from_hex_str")]
97 #[serde(rename = "author_flair_background_color")]
98 pub background_color: Option<Color>,
99
100 #[serde(rename = "author_flair_template_id")]
101 pub template_id: Option<AuthorFlairTemplateId>,
102
103 #[serde(rename = "author_flair_css_class")]
104 pub css_class: Option<String>,
105
106 #[serde(rename = "author_flair_richtext")]
107 pub richtext: Option<Vec<Richtext>>,
108
109 #[serde(with = "serde_with::rust::string_empty_as_none")]
110 #[serde(rename = "author_flair_text_color")]
111 pub text_color: Option<FlairTextColor>,
112
113 #[serde(rename = "author_flair_type")]
114 pub ty: Option<FlairType>,
115
116 #[serde(rename = "author_flair_text")]
117 pub text: Option<String>,
118}
119
120#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
121pub struct AuthorFlairTemplateId(Uuid);
122
123#[cfg(test)]
124mod test_author {
125 #![allow(clippy::non_ascii_literal)] use super::*;
128
129 #[test]
130 fn test_deserialize() {
131 let json = r##"
132 {
133 "author": "dermeister1985",
134 "author_flair_background_color": "#dadada",
135 "author_flair_css_class": "flazy",
136 "author_flair_richtext": [
137 {
138 "e": "text",
139 "t": "лл"
140 }
141 ],
142 "author_flair_template_id": "3e1b76b8-6266-11e9-ad04-0e5925592ac0",
143 "author_flair_text": "лл",
144 "author_flair_text_color": "dark",
145 "author_flair_type": "richtext",
146 "author_fullname": "t2_3mdzj3s7",
147 "author_is_blocked": false,
148 "author_patreon_flair": false,
149 "author_premium": false
150 }"##;
151
152 dbg!(serde_json::from_str::<Author>(json).unwrap());
153 }
154}