Files
100-exercises-to-learn-rust/helpers/ticket_fields/src/description.rs

74 lines
1.9 KiB
Rust

#[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 bytes")]
TooLong,
}
impl TryFrom<String> for TicketDescription {
type Error = TicketDescriptionError;
fn try_from(value: String) -> Result<Self, Self::Error> {
validate(&value)?;
Ok(Self(value))
}
}
impl TryFrom<&str> for TicketDescription {
type Error = TicketDescriptionError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
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 bytes"
);
}
#[test]
fn test_try_from_str() {
let description = TicketDescription::try_from("A description").unwrap();
assert_eq!(description.0, "A description");
}
}