serenity/builder/
create_embed.rs1#[cfg(feature = "http")]
18use crate::internal::prelude::*;
19use crate::model::prelude::*;
20
21#[derive(Clone, Debug, Serialize, PartialEq)]
25#[must_use]
26pub struct CreateEmbed(Embed);
27
28impl CreateEmbed {
29 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn author(mut self, author: CreateEmbedAuthor) -> Self {
38 self.0.author = Some(author.0);
39 self
40 }
41
42 #[inline]
46 pub fn color<C: Into<Colour>>(self, colour: C) -> Self {
47 self.colour(colour)
48 }
49
50 #[inline]
52 pub fn colour<C: Into<Colour>>(mut self, colour: C) -> Self {
53 self.0.colour = Some(colour.into());
54 self
55 }
56
57 #[inline]
61 pub fn description(mut self, description: impl Into<String>) -> Self {
62 self.0.description = Some(description.into());
63 self
64 }
65
66 #[inline]
71 pub fn field(
72 mut self,
73 name: impl Into<String>,
74 value: impl Into<String>,
75 inline: bool,
76 ) -> Self {
77 self.0.fields.push(EmbedField::new(name, value, inline));
78 self
79 }
80
81 pub fn fields<N, V>(mut self, fields: impl IntoIterator<Item = (N, V, bool)>) -> Self
85 where
86 N: Into<String>,
87 V: Into<String>,
88 {
89 let fields =
90 fields.into_iter().map(|(name, value, inline)| EmbedField::new(name, value, inline));
91 self.0.fields.extend(fields);
92 self
93 }
94
95 pub fn footer(mut self, footer: CreateEmbedFooter) -> Self {
99 self.0.footer = Some(footer.0);
100 self
101 }
102
103 #[inline]
108 pub fn image(mut self, url: impl Into<String>) -> Self {
109 self.0.image = Some(EmbedImage {
110 url: url.into(),
111 proxy_url: None,
112 height: None,
113 width: None,
114 });
115 self
116 }
117
118 #[inline]
120 pub fn thumbnail(mut self, url: impl Into<String>) -> Self {
121 self.0.thumbnail = Some(EmbedThumbnail {
122 url: url.into(),
123 proxy_url: None,
124 height: None,
125 width: None,
126 });
127 self
128 }
129
130 #[inline]
145 pub fn timestamp<T: Into<Timestamp>>(mut self, timestamp: T) -> Self {
146 self.0.timestamp = Some(timestamp.into());
147 self
148 }
149
150 #[inline]
152 pub fn title(mut self, title: impl Into<String>) -> Self {
153 self.0.title = Some(title.into());
154 self
155 }
156
157 #[inline]
159 pub fn url(mut self, url: impl Into<String>) -> Self {
160 self.0.url = Some(url.into());
161 self
162 }
163
164 #[inline]
173 pub fn attachment(self, filename: impl Into<String>) -> Self {
174 let mut filename = filename.into();
175 filename.insert_str(0, "attachment://");
176 self.image(filename)
177 }
178
179 #[cfg(feature = "http")]
180 pub(super) fn check_length(&self) -> Result<()> {
181 let mut length = 0;
182 if let Some(ref author) = self.0.author {
183 length += author.name.chars().count();
184 }
185
186 if let Some(ref description) = self.0.description {
187 length += description.chars().count();
188 }
189
190 for field in &self.0.fields {
191 length += field.name.chars().count();
192 length += field.value.chars().count();
193 }
194
195 if let Some(ref footer) = self.0.footer {
196 length += footer.text.chars().count();
197 }
198
199 if let Some(ref title) = self.0.title {
200 length += title.chars().count();
201 }
202
203 super::check_overflow(length, crate::constants::EMBED_MAX_LENGTH)
204 .map_err(|overflow| Error::Model(ModelError::EmbedTooLarge(overflow)))
205 }
206}
207
208impl Default for CreateEmbed {
209 fn default() -> Self {
211 Self(Embed {
212 fields: Vec::new(),
213 description: None,
214 thumbnail: None,
215 timestamp: None,
216 kind: Some("rich".into()),
217 author: None,
218 colour: None,
219 footer: None,
220 image: None,
221 title: None,
222 url: None,
223 video: None,
224 provider: None,
225 })
226 }
227}
228
229impl From<Embed> for CreateEmbed {
230 fn from(embed: Embed) -> Self {
231 Self(embed)
232 }
233}
234
235#[derive(Clone, Debug, Serialize)]
237#[must_use]
238pub struct CreateEmbedAuthor(EmbedAuthor);
239
240impl CreateEmbedAuthor {
241 pub fn new(name: impl Into<String>) -> Self {
243 Self(EmbedAuthor {
244 name: name.into(),
245 icon_url: None,
246 url: None,
247 proxy_icon_url: None,
249 })
250 }
251
252 pub fn name(mut self, name: impl Into<String>) -> Self {
254 self.0.name = name.into();
255 self
256 }
257
258 pub fn icon_url(mut self, icon_url: impl Into<String>) -> Self {
260 self.0.icon_url = Some(icon_url.into());
261 self
262 }
263
264 pub fn url(mut self, url: impl Into<String>) -> Self {
266 self.0.url = Some(url.into());
267 self
268 }
269}
270
271impl From<EmbedAuthor> for CreateEmbedAuthor {
272 fn from(author: EmbedAuthor) -> Self {
273 Self(author)
274 }
275}
276
277#[cfg(feature = "model")]
278impl From<User> for CreateEmbedAuthor {
279 fn from(user: User) -> Self {
280 let avatar_icon = user.face();
281 Self::new(user.name).icon_url(avatar_icon)
282 }
283}
284
285#[cfg(feature = "model")]
286impl From<&User> for CreateEmbedAuthor {
287 fn from(user: &User) -> Self {
288 let avatar_icon = user.face();
289 Self::new(user.name.clone()).icon_url(avatar_icon)
290 }
291}
292
293#[derive(Clone, Debug, Serialize)]
295#[must_use]
296pub struct CreateEmbedFooter(EmbedFooter);
297
298impl CreateEmbedFooter {
299 pub fn new(text: impl Into<String>) -> Self {
301 Self(EmbedFooter {
302 text: text.into(),
303 icon_url: None,
304 proxy_icon_url: None,
306 })
307 }
308
309 pub fn text(mut self, text: impl Into<String>) -> Self {
311 self.0.text = text.into();
312 self
313 }
314
315 pub fn icon_url(mut self, icon_url: impl Into<String>) -> Self {
319 self.0.icon_url = Some(icon_url.into());
320 self
321 }
322}
323
324impl From<EmbedFooter> for CreateEmbedFooter {
325 fn from(footer: EmbedFooter) -> Self {
326 Self(footer)
327 }
328}