slack_morphism/models/common/
icon.rs1use rsb_derive::Builder;
2use serde::de::{MapAccess, Visitor};
3use serde::ser::SerializeMap;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use serde_with::skip_serializing_none;
6use std::*;
7
8#[skip_serializing_none]
9#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
10pub struct SlackIcon {
11 pub image_original: Option<String>,
12 pub image_default: Option<bool>,
13 #[serde(flatten)]
14 pub images: Option<SlackIconImages>,
15}
16
17#[skip_serializing_none]
18#[derive(Debug, PartialEq, Clone, Builder)]
19pub struct SlackIconImages {
20 pub resolutions: Vec<(u32, String)>,
21}
22
23const SLACK_ICON_JSON_PREFIX: &str = "image_";
24
25impl Serialize for SlackIconImages {
26 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27 where
28 S: Serializer,
29 {
30 if self.resolutions.is_empty() {
31 serializer.serialize_none()
32 } else {
33 let mut res_map = serializer.serialize_map(Some(self.resolutions.len()))?;
34 for (res, link) in &self.resolutions {
35 let key: String = format!("{SLACK_ICON_JSON_PREFIX}{res}");
36 res_map.serialize_entry(&key, link)?;
37 }
38 res_map.end()
39 }
40 }
41}
42
43struct SlackIconImagesVisitor {}
44
45impl SlackIconImagesVisitor {
46 fn new() -> Self {
47 Self {}
48 }
49}
50
51impl<'de> Visitor<'de> for SlackIconImagesVisitor {
52 type Value = SlackIconImages;
53
54 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
55 formatter.write_str("a json contains images_ for icon")
56 }
57
58 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
59 where
60 M: MapAccess<'de>,
61 {
62 let mut resolutions: Vec<(u32, String)> =
63 Vec::with_capacity(access.size_hint().unwrap_or(0));
64
65 while let Some(key) = access.next_key::<String>()? {
66 if key.starts_with(SLACK_ICON_JSON_PREFIX) {
67 let parsed_key: Vec<_> = key.split('_').collect();
68 if parsed_key.len() == 2 {
69 let resolution: u32 = parsed_key[1].parse().unwrap();
70 let value: String = access.next_value()?;
71 resolutions.push((resolution, value).clone());
72 }
73 }
74 }
75
76 Ok(SlackIconImages::new(resolutions))
77 }
78}
79
80impl<'de> Deserialize<'de> for SlackIconImages {
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 deserializer.deserialize_map(SlackIconImagesVisitor::new())
86 }
87}