use std::fmt::Display;
use std::fmt::Formatter;
use std::str::FromStr;
use super::portable_name::is_portable;
use crate::error::ParseApplicationNameError;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct ApplicationName(String);
impl ApplicationName {
pub fn get(&self) -> &str {
&self.0
}
}
impl Display for ApplicationName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
impl FromStr for ApplicationName {
type Err = ParseApplicationNameError;
fn from_str(name: &str) -> Result<Self, Self::Err> {
Self::try_from(name.to_owned())
}
}
impl TryFrom<&str> for ApplicationName {
type Error = ParseApplicationNameError;
fn try_from(name: &str) -> Result<Self, Self::Error> {
Self::try_from(name.to_owned())
}
}
impl TryFrom<String> for ApplicationName {
type Error = ParseApplicationNameError;
fn try_from(name: String) -> Result<Self, Self::Error> {
if is_portable(&name) {
Ok(Self(name))
} else {
Err(ParseApplicationNameError::MalformedName { name })
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::missing_panics_doc)]
use super::*;
#[test]
fn from_str_with_a_malformed_name_returns_an_error() {
let error = "example/app".parse::<ApplicationName>().unwrap_err();
assert!(matches!(
error,
ParseApplicationNameError::MalformedName { .. }
));
}
#[test]
fn from_str_with_a_portable_name_returns_the_name() {
let name: ApplicationName = "example".parse().unwrap();
assert_eq!(name.get(), "example");
}
#[test]
fn to_string_of_the_error_escapes_the_value() {
let error = "COM1\n".parse::<ApplicationName>().unwrap_err();
assert_eq!(
error.to_string(),
"the application name \"COM1\\n\" is malformed, because a name holds 1 to 250 ASCII letters, digits, and hyphens, and does not name a device on Windows"
);
}
#[test]
fn try_from_a_str_with_a_malformed_name_returns_an_error() {
let error = ApplicationName::try_from("").unwrap_err();
assert!(matches!(
error,
ParseApplicationNameError::MalformedName { .. }
));
}
#[test]
fn try_from_a_string_with_a_malformed_name_returns_an_error() {
let error = ApplicationName::try_from(String::from("..")).unwrap_err();
assert!(matches!(
error,
ParseApplicationNameError::MalformedName { .. }
));
}
}