vstorage 0.7.0

Common API for various icalendar/vcard storages.
Documentation
//! Collection properties.
//!
//! Storages expose properties for collections. Valid properties vary depending on a storage's
//! item kind. Items themselves cannot have properties.

use crate::ItemKind;

/// Property which can be read, written or unset for collections.
///
/// These were known as "metadata" in the original vdirsyncer implementation.
///
/// See also [`Storage::get_property`] and [`Storage::set_property`].
///
/// [`Storage::get_property`]: crate::base::Storage::get_property
/// [`Storage::set_property`]: crate::base::Storage::set_property
#[derive(Clone, Copy, Debug, std::hash::Hash, PartialEq, Eq)]
#[non_exhaustive]
pub enum Property {
    /// User-friendly name for a collection.
    ///
    /// It is recommended to show this name in user interfaces.
    DisplayName,
    /// Human readable description of the collection.
    Description,
    /// Colour to be used when displaying this collection.
    ///
    /// Graphical interfaces may use this for the collection itself or its items.
    ///
    /// Only valid for calendars.
    Colour,
    /// Sorting order for this collection.
    ///
    /// Only valid for calendars.
    Order,
}

impl Property {
    /// Return a friendly name for this property.
    #[must_use]
    pub fn name(&self) -> &'static str {
        match self {
            Property::DisplayName => "displayname",
            Property::Colour => "color",
            Property::Description => "description",
            Property::Order => "order",
        }
    }

    /// Return all known properties of a given kind.
    #[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],
        }
    }

    /// Whether this property is valid for the given item kind.
    #[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"),
        }
    }
}