slack_messaging/blocks/data_visualization/charts/
segment.rs1use crate::errors::ValidationErrors;
2use crate::validators::*;
3
4use serde::Serialize;
5use serde_json::Number;
6use slack_messaging_derive::Builder;
7
8#[derive(Debug, Clone, Serialize, PartialEq, Builder)]
48pub struct Segment {
49 #[builder(validate("required", "text::max_20"))]
50 pub(crate) label: Option<String>,
51
52 #[builder(validate("required", "number::greater_than_zero"))]
53 pub(crate) value: Option<Number>,
54}
55
56impl<S, N> TryFrom<(S, N)> for Segment
57where
58 S: Into<String>,
59 N: Into<Number>,
60{
61 type Error = ValidationErrors;
62
63 fn try_from(value: (S, N)) -> Result<Self, Self::Error> {
64 let (label, value) = value;
65 Segment::builder()
66 .label(label)
67 .value(value)
68 .build()
69 }
70}
71
72pub fn segments<Iter, S, N>(iter: Iter) -> Result<Vec<Segment>, ValidationErrors>
98where
99 Iter: IntoIterator<Item = (S, N)>,
100 S: Into<String>,
101 N: Into<Number>,
102{
103 iter.into_iter().map(Segment::try_from).collect()
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use crate::errors::*;
110
111 #[test]
112 fn it_implements_builder() {
113 let expected = Segment {
114 label: Some("Segment A".to_string()),
115 value: Some(Number::from(100)),
116 };
117
118 let val = Segment::builder()
119 .set_label(Some("Segment A"))
120 .set_value(Some(100))
121 .build()
122 .unwrap();
123
124 assert_eq!(val, expected);
125
126 let val = Segment::builder()
127 .label("Segment A")
128 .value(100)
129 .build()
130 .unwrap();
131
132 assert_eq!(val, expected);
133 }
134
135 #[test]
136 fn it_implements_try_from_tuple() {
137 let expected = Segment {
138 label: Some("Segment A".to_string()),
139 value: Some(Number::from(100)),
140 };
141
142 let val = Segment::try_from(("Segment A", 100)).unwrap();
143
144 assert_eq!(val, expected);
145 }
146
147 #[test]
148 fn it_implements_segments_function() {
149 let expected = vec![
150 Segment {
151 label: Some("Segment A".to_string()),
152 value: Some(Number::from(100)),
153 },
154 Segment {
155 label: Some("Segment B".to_string()),
156 value: Some(Number::from(200)),
157 },
158 ];
159
160 let val = segments(vec![("Segment A", 100), ("Segment B", 200)]).unwrap();
161
162 assert_eq!(val, expected);
163 }
164
165 #[test]
166 fn it_requires_label_field() {
167 let err = Segment::builder().value(100).build().unwrap_err();
168 assert_eq!(err.object(), "Segment");
169
170 let errors = err.field("label");
171 assert!(errors.includes(ValidationErrorKind::Required));
172 }
173
174 #[test]
175 fn it_requires_label_field_less_than_20_characters_long() {
176 let err = Segment::builder()
177 .label("a".repeat(21))
178 .value(100)
179 .build()
180 .unwrap_err();
181 assert_eq!(err.object(), "Segment");
182
183 let errors = err.field("label");
184 assert!(errors.includes(ValidationErrorKind::MaxTextLength(20)));
185 }
186
187 #[test]
188 fn it_requires_value_field() {
189 let err = Segment::builder().label("Segment A").build().unwrap_err();
190 assert_eq!(err.object(), "Segment");
191
192 let errors = err.field("value");
193 assert!(errors.includes(ValidationErrorKind::Required));
194 }
195
196 #[test]
197 fn it_requires_value_field_greater_than_zero() {
198 let err = Segment::builder()
199 .label("Segment A")
200 .value(0)
201 .build()
202 .unwrap_err();
203 assert_eq!(err.object(), "Segment");
204
205 let errors = err.field("value");
206 assert!(errors.includes(ValidationErrorKind::MustBeGreaterThanZero));
207 }
208}