1use crate::error::Result;
2use crate::{Attachment, SlackText};
3use reqwest::Url;
4use serde::{Serialize, Serializer};
5
6#[derive(Serialize, Debug, Default)]
10pub struct Payload {
11 #[serde(skip_serializing_if = "Option::is_none")]
14 pub text: Option<SlackText>,
15 #[serde(skip_serializing_if = "Option::is_none")]
19 pub channel: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub username: Option<String>,
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub icon_url: Option<Url>,
26 #[serde(skip_serializing_if = "Option::is_none")]
29 pub icon_emoji: Option<String>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub attachments: Option<Vec<Attachment>>,
33 #[serde(skip_serializing_if = "Option::is_none")]
36 pub unfurl_links: Option<bool>,
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub unfurl_media: Option<bool>,
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub link_names: Option<u8>,
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub parse: Option<Parse>,
46}
47
48#[derive(Debug)]
50pub enum Parse {
51 Full,
53 None,
55}
56
57impl Serialize for Parse {
58 fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
59 where
60 S: Serializer,
61 {
62 let st = match *self {
63 Parse::Full => "full",
64 Parse::None => "none",
65 };
66 serializer.serialize_str(st)
67 }
68}
69#[derive(Debug)]
71pub struct PayloadBuilder {
72 inner: Result<Payload>,
73}
74
75impl Default for PayloadBuilder {
76 fn default() -> PayloadBuilder {
77 PayloadBuilder {
78 inner: Ok(Default::default()),
79 }
80 }
81}
82
83impl PayloadBuilder {
84 pub fn new() -> PayloadBuilder {
86 Default::default()
87 }
88
89 pub fn text<S: Into<SlackText>>(self, text: S) -> PayloadBuilder {
91 match self.inner {
92 Ok(mut inner) => {
93 inner.text = Some(text.into());
94 PayloadBuilder { inner: Ok(inner) }
95 }
96 _ => self,
97 }
98 }
99
100 pub fn channel<S: Into<String>>(self, channel: S) -> PayloadBuilder {
102 match self.inner {
103 Ok(mut inner) => {
104 inner.channel = Some(channel.into());
105 PayloadBuilder { inner: Ok(inner) }
106 }
107 _ => self,
108 }
109 }
110
111 pub fn username<S: Into<String>>(self, username: S) -> PayloadBuilder {
113 match self.inner {
114 Ok(mut inner) => {
115 inner.username = Some(username.into());
116 PayloadBuilder { inner: Ok(inner) }
117 }
118 _ => self,
119 }
120 }
121
122 pub fn icon_emoji<S: Into<String>>(self, icon_emoji: S) -> PayloadBuilder {
124 match self.inner {
125 Ok(mut inner) => {
126 inner.icon_emoji = Some(icon_emoji.into());
127 PayloadBuilder { inner: Ok(inner) }
128 }
129 _ => self,
130 }
131 }
132
133 url_builder_fn! {
134 icon_url, PayloadBuilder
136 }
137
138 pub fn attachments(self, attachments: Vec<Attachment>) -> PayloadBuilder {
140 match self.inner {
141 Ok(mut inner) => {
142 inner.attachments = Some(attachments);
143 PayloadBuilder { inner: Ok(inner) }
144 }
145 _ => self,
146 }
147 }
148
149 pub fn unfurl_links(self, b: bool) -> PayloadBuilder {
152 match self.inner {
153 Ok(mut inner) => {
154 inner.unfurl_links = Some(b);
155 PayloadBuilder { inner: Ok(inner) }
156 }
157 _ => self,
158 }
159 }
160
161 pub fn unfurl_media(self, b: bool) -> PayloadBuilder {
163 match self.inner {
164 Ok(mut inner) => {
165 inner.unfurl_media = Some(b);
166 PayloadBuilder { inner: Ok(inner) }
167 }
168 _ => self,
169 }
170 }
171
172 pub fn link_names(self, b: bool) -> PayloadBuilder {
177 match self.inner {
178 Ok(mut inner) => {
179 inner.link_names = Some(u8::from(b));
180 PayloadBuilder { inner: Ok(inner) }
181 }
182 _ => self,
183 }
184 }
185
186 pub fn parse(self, p: Parse) -> PayloadBuilder {
188 match self.inner {
189 Ok(mut inner) => {
190 inner.parse = Some(p);
191 PayloadBuilder { inner: Ok(inner) }
192 }
193 _ => self,
194 }
195 }
196
197 pub fn build(self) -> Result<Payload> {
199 self.inner
200 }
201}