ezcal 0.3.4

Ergonomic iCalendar + vCard library for Rust
Documentation
use crate::common::property::Property;
use std::fmt;

/// The action type for an alarm.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AlarmAction {
    Audio,
    Display,
    Email,
    Other(String),
}

impl AlarmAction {
    pub fn parse(s: &str) -> Self {
        match s.to_uppercase().as_str() {
            "AUDIO" => AlarmAction::Audio,
            "DISPLAY" => AlarmAction::Display,
            "EMAIL" => AlarmAction::Email,
            other => AlarmAction::Other(other.to_string()),
        }
    }
}

impl fmt::Display for AlarmAction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            AlarmAction::Audio => write!(f, "AUDIO"),
            AlarmAction::Display => write!(f, "DISPLAY"),
            AlarmAction::Email => write!(f, "EMAIL"),
            AlarmAction::Other(s) => write!(f, "{}", s),
        }
    }
}

/// A VALARM component (alarm/reminder).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Alarm {
    pub action: AlarmAction,
    pub trigger: String,
    pub description: Option<String>,
    pub summary: Option<String>,
    pub duration: Option<String>,
    pub repeat: Option<u32>,
    pub extra_properties: Vec<Property>,
}

impl Alarm {
    /// Create a new display alarm with the given trigger.
    ///
    /// The trigger should be a duration (e.g., `-PT15M` for 15 minutes before)
    /// or an absolute date-time.
    pub fn display(trigger: impl Into<String>, description: impl Into<String>) -> Self {
        Self {
            action: AlarmAction::Display,
            trigger: trigger.into(),
            description: Some(description.into()),
            summary: None,
            duration: None,
            repeat: None,
            extra_properties: Vec::new(),
        }
    }

    /// Create a new audio alarm with the given trigger.
    pub fn audio(trigger: impl Into<String>) -> Self {
        Self {
            action: AlarmAction::Audio,
            trigger: trigger.into(),
            description: None,
            summary: None,
            duration: None,
            repeat: None,
            extra_properties: Vec::new(),
        }
    }

    pub fn with_repeat(mut self, duration: impl Into<String>, repeat: u32) -> Self {
        self.duration = Some(duration.into());
        self.repeat = Some(repeat);
        self
    }

    pub(crate) fn to_properties(&self) -> Vec<Property> {
        let mut props = Vec::new();
        props.push(Property::new("ACTION", self.action.to_string()));
        props.push(Property::new("TRIGGER", &self.trigger));
        if let Some(ref desc) = self.description {
            props.push(Property::new("DESCRIPTION", desc));
        }
        if let Some(ref summary) = self.summary {
            props.push(Property::new("SUMMARY", summary));
        }
        if let Some(ref dur) = self.duration {
            props.push(Property::new("DURATION", dur));
        }
        if let Some(rep) = self.repeat {
            props.push(Property::new("REPEAT", rep.to_string()));
        }
        props.extend(self.extra_properties.clone());
        props
    }
}