use std::str::FromStr;
use crate::ItemKind;
#[derive(Clone, Copy, Debug, std::hash::Hash, PartialEq, Eq)]
#[non_exhaustive]
pub enum Property {
DisplayName,
Description,
Colour,
Order,
}
impl Property {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Property::DisplayName => "displayname",
Property::Colour => "color",
Property::Description => "description",
Property::Order => "order",
}
}
#[must_use]
pub fn known_properties(item_kind: ItemKind) -> &'static [Self] {
match item_kind {
ItemKind::Calendar => &[
Property::DisplayName,
Property::Colour,
Property::Description,
Property::Order,
],
ItemKind::AddressBook => &[Property::DisplayName, Property::Description],
}
}
#[must_use]
pub fn is_valid_for(&self, item_kind: ItemKind) -> bool {
match self {
Property::DisplayName | Property::Description => true,
Property::Colour | Property::Order => item_kind == ItemKind::Calendar,
}
}
}
impl std::fmt::Display for Property {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Property::Colour => f.write_str("colour"),
Property::DisplayName => f.write_str("display name"),
Property::Description => f.write_str("description"),
Property::Order => f.write_str("order"),
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("Not a valid property name.")]
pub struct Invalid;
impl FromStr for Property {
type Err = Invalid;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"color" => Ok(Property::Colour),
"displayname" => Ok(Property::DisplayName),
"description" => Ok(Property::Description),
"order" => Ok(Property::Order),
_ => Err(Invalid),
}
}
}
#[cfg(test)]
mod test {
use crate::{ItemKind, property::Property};
#[test]
fn parses_all_values() {
for property in Property::known_properties(ItemKind::Calendar) {
assert_eq!(&property.name().parse::<Property>().unwrap(), property);
}
}
}