use zcheapstr::CheapStr;
use crate::parse;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TypeName<'a>(pub(crate) CheapStr<'a>);
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OwnedTypeName(TypeName<'static>);
impl_name!(
TypeName,
OwnedTypeName,
is_valid_type_name,
crate::Error::InvalidTypeName,
"a Varlink type name"
);
pub fn is_valid_type_name(name: &str) -> bool {
parse::parses_fully(parse::type_name, name)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Error, is_valid_field_name};
#[test]
fn type_names() {
let valid = ["A", "Foo", "FileNotFound", "Foo0", "X"];
for name in valid {
assert!(is_valid_type_name(name), "`{name}` must be valid");
}
let invalid = [
"", "foo", "_Foo", "0Foo", "Foo_bar", "Foo-bar", "Foo bar", "Foo.Bar", "Foo!", "Über",
];
for name in invalid {
assert!(!is_valid_type_name(name), "`{name}` must be invalid");
}
}
#[test]
fn type_names_are_field_names() {
for name in ["A", "Foo", "FileNotFound", "Foo0"] {
assert!(is_valid_field_name(name), "`{name}` must be valid");
}
}
#[test]
fn try_from() {
let name = TypeName::try_from("FileNotFound").unwrap();
assert_eq!(name.as_str(), "FileNotFound");
let name = TypeName::try_from(String::from("FileNotFound")).unwrap();
assert_eq!(name.as_str(), "FileNotFound");
assert_eq!(
TypeName::try_from("fileNotFound"),
Err(Error::InvalidTypeName)
);
assert_eq!(
TypeName::try_from(String::from("File_not_found")),
Err(Error::InvalidTypeName)
);
}
#[test]
fn owned_try_from() {
let name = OwnedTypeName::try_from("FileNotFound").unwrap();
assert_eq!(name.as_str(), "FileNotFound");
let name = OwnedTypeName::try_from(String::from("FileNotFound")).unwrap();
assert_eq!(name.as_str(), "FileNotFound");
assert_eq!(
OwnedTypeName::try_from("fileNotFound"),
Err(Error::InvalidTypeName)
);
assert_eq!(
OwnedTypeName::try_from(String::new()),
Err(Error::InvalidTypeName)
);
}
}