1use crate::{Attachment, SlackText};
2use crate::helper::bool_to_u8;
3use crate::error::Result;
4use serde::{Serialize, Serializer};
5use url::Url;
6
7#[derive(Serialize, Debug, Default)]
11pub struct Payload {
12 #[serde(skip_serializing_if = "Option::is_none")]
15 pub text: Option<SlackText>,
16 #[serde(skip_serializing_if = "Option::is_none")]
20 pub channel: Option<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub username: Option<String>,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub icon_url: Option<Url>,
27 #[serde(skip_serializing_if = "Option::is_none")]
30 pub icon_emoji: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub attachments: Option<Vec<Attachment>>,
34 #[serde(skip_serializing_if = "Option::is_none")]
37 pub unfurl_links: Option<bool>,
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub unfurl_media: Option<bool>,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub link_names: Option<u8>,
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub parse: Option<Parse>,
47}
48
49#[derive(Debug)]
51pub enum Parse {
52 Full,
54 None,
56}
57
58impl Serialize for Parse {
59 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
60 where
61 S: Serializer,
62 {
63 let st = match *self {
64 Parse::Full => "full",
65 Parse::None => "none",
66 };
67 serializer.serialize_str(st)
68 }
69}
70#[derive(Debug)]
72pub struct PayloadBuilder {
73 inner: Result<Payload>,
74}
75
76impl Default for PayloadBuilder {
77 fn default() -> PayloadBuilder {
78 PayloadBuilder {
79 inner: Ok(Default::default()),
80 }
81 }
82}
83
84impl PayloadBuilder {
85 pub fn new() -> PayloadBuilder {
87 Default::default()
88 }
89
90 pub fn text<S: Into<SlackText>>(self, text: S) -> PayloadBuilder {
92 match self.inner {
93 Ok(mut inner) => {
94 inner.text = Some(text.into());
95 PayloadBuilder { inner: Ok(inner) }
96 }
97 _ => self,
98 }
99 }
100
101 pub fn channel<S: Into<String>>(self, channel: S) -> PayloadBuilder {
103 match self.inner {
104 Ok(mut inner) => {
105 inner.channel = Some(channel.into());
106 PayloadBuilder { inner: Ok(inner) }
107 }
108 _ => self,
109 }
110 }
111
112 pub fn username<S: Into<String>>(self, username: S) -> PayloadBuilder {
114 match self.inner {
115 Ok(mut inner) => {
116 inner.username = Some(username.into());
117 PayloadBuilder { inner: Ok(inner) }
118 }
119 _ => self,
120 }
121 }
122
123 pub fn icon_emoji<S: Into<String>>(self, icon_emoji: S) -> PayloadBuilder {
125 match self.inner {
126 Ok(mut inner) => {
127 inner.icon_emoji = Some(icon_emoji.into());
128 PayloadBuilder { inner: Ok(inner) }
129 }
130 _ => self,
131 }
132 }
133
134 url_builder_fn! {
135 icon_url, PayloadBuilder
137 }
138
139 pub fn attachments(self, attachments: Vec<Attachment>) -> PayloadBuilder {
141 match self.inner {
142 Ok(mut inner) => {
143 inner.attachments = Some(attachments);
144 PayloadBuilder { inner: Ok(inner) }
145 }
146 _ => self,
147 }
148 }
149
150 pub fn unfurl_links(self, b: bool) -> PayloadBuilder {
153 match self.inner {
154 Ok(mut inner) => {
155 inner.unfurl_links = Some(b);
156 PayloadBuilder { inner: Ok(inner) }
157 }
158 _ => self,
159 }
160 }
161
162 pub fn unfurl_media(self, b: bool) -> PayloadBuilder {
164 match self.inner {
165 Ok(mut inner) => {
166 inner.unfurl_media = Some(b);
167 PayloadBuilder { inner: Ok(inner) }
168 }
169 _ => self,
170 }
171 }
172
173 pub fn link_names(self, b: bool) -> PayloadBuilder {
178 match self.inner {
179 Ok(mut inner) => {
180 inner.link_names = Some(bool_to_u8(b));
181 PayloadBuilder { inner: Ok(inner) }
182 }
183 _ => self,
184 }
185 }
186
187 pub fn parse(self, p: Parse) -> PayloadBuilder {
189 match self.inner {
190 Ok(mut inner) => {
191 inner.parse = Some(p);
192 PayloadBuilder { inner: Ok(inner) }
193 }
194 _ => self,
195 }
196 }
197
198 pub fn build(self) -> Result<Payload> {
200 self.inner
201 }
202}