twilight_embed_builder/
footer.rs1use super::image_source::ImageSource;
4use twilight_model::channel::embed::EmbedFooter;
5
6#[derive(Clone, Debug, Eq, PartialEq)]
12#[must_use = "must be built into an embed footer"]
13pub struct EmbedFooterBuilder(EmbedFooter);
14
15impl EmbedFooterBuilder {
16 pub fn new(text: impl Into<String>) -> Self {
23 Self::_new(text.into())
24 }
25
26 const fn _new(text: String) -> Self {
27 Self(EmbedFooter {
28 icon_url: None,
29 proxy_icon_url: None,
30 text,
31 })
32 }
33
34 #[allow(clippy::missing_const_for_fn)]
36 #[must_use = "should be used as part of an embed builder"]
37 pub fn build(self) -> EmbedFooter {
38 self.0
39 }
40
41 pub fn icon_url(mut self, image_source: ImageSource) -> Self {
58 self.0.icon_url.replace(image_source.0);
59
60 self
61 }
62}
63
64impl From<EmbedFooterBuilder> for EmbedFooter {
65 fn from(builder: EmbedFooterBuilder) -> Self {
69 builder.build()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::EmbedFooterBuilder;
76 use crate::{EmbedBuilder, EmbedErrorType, ImageSource};
77 use static_assertions::assert_impl_all;
78 use std::fmt::Debug;
79 use twilight_model::channel::embed::EmbedFooter;
80
81 assert_impl_all!(EmbedFooterBuilder: Clone, Debug, Eq, PartialEq, Send, Sync);
82 assert_impl_all!(EmbedFooter: From<EmbedFooterBuilder>);
83
84 #[test]
85 fn text() {
86 assert!(matches!(
87 EmbedBuilder::new().footer(EmbedFooterBuilder::new("")).build().unwrap_err().kind(),
88 EmbedErrorType::FooterTextEmpty { text }
89 if text.is_empty()
90 ));
91 let too_long_len = EmbedBuilder::FOOTER_TEXT_LENGTH_LIMIT + 1;
92 assert!(matches!(
93 EmbedBuilder::new().footer(EmbedFooterBuilder::new("a".repeat(too_long_len))).build().unwrap_err().kind(),
94 EmbedErrorType::FooterTextTooLong { text }
95 if text.len() == too_long_len
96 ));
97
98 let expected = EmbedFooter {
99 icon_url: None,
100 proxy_icon_url: None,
101 text: "a footer".to_owned(),
102 };
103 let actual = EmbedFooterBuilder::new("a footer").build();
104 assert_eq!(actual, expected);
105 }
106
107 #[test]
108 fn builder() {
109 let expected = EmbedFooter {
110 icon_url: Some("https://example.com/1.png".to_owned()),
111 proxy_icon_url: None,
112 text: "a footer".to_owned(),
113 };
114 let image = ImageSource::url("https://example.com/1.png").unwrap();
115 let actual = EmbedFooterBuilder::new("a footer").icon_url(image).build();
116 assert_eq!(actual, expected);
117 }
118}