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