#[derive(Debug, PartialEq, Clone, Eq)] pub struct TicketDescription(String); #[derive(Debug, thiserror::Error)] pub enum TicketDescriptionError { #[error("The description cannot be empty")] Empty, #[error("The description cannot be longer than 500 characters")] TooLong, } impl TryFrom for TicketDescription { type Error = TicketDescriptionError; fn try_from(value: String) -> Result { validate(&value)?; Ok(Self(value)) } } impl TryFrom<&str> for TicketDescription { type Error = TicketDescriptionError; fn try_from(value: &str) -> Result { validate(value)?; Ok(Self(value.to_string())) } } fn validate(description: &str) -> Result<(), TicketDescriptionError> { if description.is_empty() { Err(TicketDescriptionError::Empty) } else if description.len() > 500 { Err(TicketDescriptionError::TooLong) } else { Ok(()) } } #[cfg(test)] mod tests { use super::*; use common::{overly_long_description, valid_description}; use std::convert::TryFrom; #[test] fn test_try_from_string() { let input = valid_description(); let description = TicketDescription::try_from(input.clone()).unwrap(); assert_eq!(description.0, input); } #[test] fn test_try_from_empty_string() { let err = TicketDescription::try_from("".to_string()).unwrap_err(); assert_eq!(err.to_string(), "The description cannot be empty"); } #[test] fn test_try_from_long_string() { let err = TicketDescription::try_from(overly_long_description()).unwrap_err(); assert_eq!( err.to_string(), "The description cannot be longer than 500 characters" ); } #[test] fn test_try_from_str() { let description = TicketDescription::try_from("A description").unwrap(); assert_eq!(description.0, "A description"); } }