use crate::errors::ValidationErrors;
use crate::validators::*;
use serde::Serialize;
use serde_json::Number;
use slack_messaging_derive::Builder;
#[derive(Debug, Clone, Serialize, PartialEq, Builder)]
pub struct Segment {
#[builder(validate("required", "text::max_20"))]
pub(crate) label: Option<String>,
#[builder(validate("required", "number::greater_than_zero"))]
pub(crate) value: Option<Number>,
}
impl<S, N> TryFrom<(S, N)> for Segment
where
S: Into<String>,
N: Into<Number>,
{
type Error = ValidationErrors;
fn try_from(value: (S, N)) -> Result<Self, Self::Error> {
let (label, value) = value;
Segment::builder()
.label(label)
.value(value)
.build()
}
}
pub fn segments<Iter, S, N>(iter: Iter) -> Result<Vec<Segment>, ValidationErrors>
where
Iter: IntoIterator<Item = (S, N)>,
S: Into<String>,
N: Into<Number>,
{
iter.into_iter().map(Segment::try_from).collect()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::errors::*;
#[test]
fn it_implements_builder() {
let expected = Segment {
label: Some("Segment A".to_string()),
value: Some(Number::from(100)),
};
let val = Segment::builder()
.set_label(Some("Segment A"))
.set_value(Some(100))
.build()
.unwrap();
assert_eq!(val, expected);
let val = Segment::builder()
.label("Segment A")
.value(100)
.build()
.unwrap();
assert_eq!(val, expected);
}
#[test]
fn it_implements_try_from_tuple() {
let expected = Segment {
label: Some("Segment A".to_string()),
value: Some(Number::from(100)),
};
let val = Segment::try_from(("Segment A", 100)).unwrap();
assert_eq!(val, expected);
}
#[test]
fn it_implements_segments_function() {
let expected = vec![
Segment {
label: Some("Segment A".to_string()),
value: Some(Number::from(100)),
},
Segment {
label: Some("Segment B".to_string()),
value: Some(Number::from(200)),
},
];
let val = segments(vec![("Segment A", 100), ("Segment B", 200)]).unwrap();
assert_eq!(val, expected);
}
#[test]
fn it_requires_label_field() {
let err = Segment::builder().value(100).build().unwrap_err();
assert_eq!(err.object(), "Segment");
let errors = err.field("label");
assert!(errors.includes(ValidationErrorKind::Required));
}
#[test]
fn it_requires_label_field_less_than_20_characters_long() {
let err = Segment::builder()
.label("a".repeat(21))
.value(100)
.build()
.unwrap_err();
assert_eq!(err.object(), "Segment");
let errors = err.field("label");
assert!(errors.includes(ValidationErrorKind::MaxTextLength(20)));
}
#[test]
fn it_requires_value_field() {
let err = Segment::builder().label("Segment A").build().unwrap_err();
assert_eq!(err.object(), "Segment");
let errors = err.field("value");
assert!(errors.includes(ValidationErrorKind::Required));
}
#[test]
fn it_requires_value_field_greater_than_zero() {
let err = Segment::builder()
.label("Segment A")
.value(0)
.build()
.unwrap_err();
assert_eq!(err.object(), "Segment");
let errors = err.field("value");
assert!(errors.includes(ValidationErrorKind::MustBeGreaterThanZero));
}
}