use components::{Component, Property};
use properties::{
Action, Description, DtStamp, DtStart, ProdID, Summary, Trigger, TzID, TzOffsetFrom,
TzOffsetTo, Version, UID
};
use std::borrow::Cow;
use std::fmt;
use std::fs::File;
use std::io::{self, Write};
use std::path::Path;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ICalendar<'a>(Component<'a>);
impl<'a> ICalendar<'a> {
pub fn new<V, P>(version: V, prodid: P) -> Self
where
V: Into<Cow<'a, str>>,
P: Into<Cow<'a, str>>
{
ICalendar(Component {
name: "VCALENDAR".into(),
properties: vec![Version::new(version).into(), ProdID::new(prodid).into()],
subcomponents: Vec::new()
})
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.add_property(property);
}
pub fn add_component<C>(&mut self, component: C)
where
C: Into<Component<'a>>
{
self.0.add_component(component);
}
pub fn add_event(&mut self, event: Event<'a>) {
self.add_component(event);
}
pub fn add_todo(&mut self, todo: ToDo<'a>) {
self.add_component(todo);
}
pub fn add_journal(&mut self, journal: Journal<'a>) {
self.add_component(journal);
}
pub fn add_freebusy(&mut self, freebusy: FreeBusy<'a>) {
self.add_component(freebusy);
}
pub fn add_timezone(&mut self, timezone: TimeZone<'a>) {
self.add_component(timezone);
}
pub fn write<W>(&self, mut writer: W) -> io::Result<()>
where
W: Write
{
write!(writer, "{}", self)
}
pub fn save_file<P>(&self, filename: P) -> io::Result<()>
where
P: AsRef<Path>
{
self.write(File::create(filename)?)
}
}
impl<'a> fmt::Display for ICalendar<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<'a> From<ICalendar<'a>> for Component<'a> {
fn from(component: ICalendar<'a>) -> Self {
component.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Event<'a> {
properties: Vec<Property<'a>>,
alarms: Vec<Alarm<'a>>
}
impl<'a> Event<'a> {
pub fn new<U, D>(uid: U, dtstamp: D) -> Self
where
U: Into<Cow<'a, str>>,
D: Into<Cow<'a, str>>
{
Self {
properties: vec![UID::new(uid).into(), DtStamp::new(dtstamp).into()],
alarms: Vec::new()
}
}
pub fn push<P: Into<Property<'a>>>(&mut self, property: P) {
self.properties.push(property.into());
}
pub fn add_alarm(&mut self, alarm: Alarm<'a>) {
self.alarms.push(alarm);
}
}
impl<'a> fmt::Display for Event<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VEVENT\r")?;
for property in &self.properties {
write!(f, "{}", property)?;
}
for component in &self.alarms {
write!(f, "{}", component)?;
}
writeln!(f, "END:VEVENT\r")
}
}
impl<'a> From<Event<'a>> for Component<'a> {
fn from(component: Event<'a>) -> Self {
Component {
name: "VEVENT".into(),
properties: component.properties,
subcomponents: component.alarms.into_iter().map(Component::from).collect()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ToDo<'a> {
properties: Vec<Property<'a>>,
alarms: Vec<Alarm<'a>>
}
impl<'a> ToDo<'a> {
pub fn new<U, D>(uid: U, dtstamp: D) -> Self
where
U: Into<Cow<'a, str>>,
D: Into<Cow<'a, str>>
{
Self {
properties: vec![UID::new(uid).into(), DtStamp::new(dtstamp).into()],
alarms: Vec::new()
}
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.properties.push(property.into());
}
pub fn add_alarm(&mut self, alarm: Alarm<'a>) {
self.alarms.push(alarm);
}
}
impl<'a> fmt::Display for ToDo<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VTODO\r")?;
for property in &self.properties {
write!(f, "{}", property)?;
}
for component in &self.alarms {
write!(f, "{}", component)?;
}
writeln!(f, "END:VTODO\r")
}
}
impl<'a> From<ToDo<'a>> for Component<'a> {
fn from(component: ToDo<'a>) -> Self {
Component {
name: "VTODO".into(),
properties: component.properties,
subcomponents: component.alarms.into_iter().map(Component::from).collect()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Journal<'a>(Vec<Property<'a>>);
impl<'a> Journal<'a> {
pub fn new<U, D>(uid: U, dtstamp: D) -> Self
where
U: Into<Cow<'a, str>>,
D: Into<Cow<'a, str>>
{
Journal(vec![UID::new(uid).into(), DtStamp::new(dtstamp).into()])
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.push(property.into());
}
}
impl<'a> fmt::Display for Journal<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VJOURNAL\r")?;
for property in &self.0 {
write!(f, "{}", property)?;
}
writeln!(f, "END:VJOURNAL\r")
}
}
impl<'a> From<Journal<'a>> for Component<'a> {
fn from(component: Journal<'a>) -> Self {
Component {
name: "VJOURNAL".into(),
properties: component.0,
subcomponents: Vec::new()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct FreeBusy<'a>(Vec<Property<'a>>);
impl<'a> FreeBusy<'a> {
pub fn new<U, D>(uid: U, dtstamp: D) -> Self
where
U: Into<Cow<'a, str>>,
D: Into<Cow<'a, str>>
{
FreeBusy(vec![UID::new(uid).into(), DtStamp::new(dtstamp).into()])
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.push(property.into());
}
}
impl<'a> fmt::Display for FreeBusy<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VFREEBUSY\r")?;
for property in &self.0 {
write!(f, "{}", property)?;
}
writeln!(f, "END:VFREEBUSY\r")
}
}
impl<'a> From<FreeBusy<'a>> for Component<'a> {
fn from(component: FreeBusy<'a>) -> Self {
Component {
name: "VFREEBUSY".into(),
properties: component.0,
subcomponents: Vec::new()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct TimeZone<'a> {
properties: Vec<Property<'a>>,
zone_times: Vec<ZoneTime<'a>>
}
impl<'a> TimeZone<'a> {
pub fn standard<S>(tzid: S, definition: Standard<'a>) -> Self
where
S: Into<Cow<'a, str>>
{
Self {
properties: vec![TzID::new(tzid).into()],
zone_times: vec![ZoneTime::Standard(definition)]
}
}
pub fn daylight<S>(tzid: S, definition: Daylight<'a>) -> Self
where
S: Into<Cow<'a, str>>
{
Self {
properties: vec![TzID::new(tzid).into()],
zone_times: vec![ZoneTime::Daylight(definition)]
}
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.properties.push(property.into());
}
pub fn add_standard(&mut self, definition: Standard<'a>) {
self.zone_times.push(ZoneTime::Standard(definition));
}
pub fn add_daylight(&mut self, definition: Daylight<'a>) {
self.zone_times.push(ZoneTime::Daylight(definition));
}
}
impl<'a> fmt::Display for TimeZone<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VTIMEZONE\r")?;
for property in &self.properties {
write!(f, "{}", property)?;
}
for component in &self.zone_times {
write!(f, "{}", component)?;
}
writeln!(f, "END:VTIMEZONE\r")
}
}
impl<'a> From<TimeZone<'a>> for Component<'a> {
fn from(component: TimeZone<'a>) -> Self {
Component {
name: "VTIMEZONE".into(),
properties: component.properties,
subcomponents: component
.zone_times
.into_iter()
.map(Component::from)
.collect()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
enum ZoneTime<'a> {
Standard(Standard<'a>),
Daylight(Daylight<'a>)
}
impl<'a> fmt::Display for ZoneTime<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ZoneTime::Daylight(p) => write!(f, "{}", p),
ZoneTime::Standard(p) => write!(f, "{}", p)
}
}
}
impl<'a> From<ZoneTime<'a>> for Component<'a> {
fn from(component: ZoneTime<'a>) -> Self {
match component {
ZoneTime::Daylight(p) => Self::from(p),
ZoneTime::Standard(p) => Self::from(p)
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Standard<'a>(Vec<Property<'a>>);
impl<'a> Standard<'a> {
pub fn new<S, T, F>(dtstart: S, tz_offset_from: F, tz_offset_to: T) -> Self
where
S: Into<Cow<'a, str>>,
F: Into<Cow<'a, str>>,
T: Into<Cow<'a, str>>
{
Standard(vec![
DtStart::new(dtstart).into(),
TzOffsetFrom::new(tz_offset_from).into(),
TzOffsetTo::new(tz_offset_to).into(),
])
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.push(property.into());
}
}
impl<'a> fmt::Display for Standard<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:STANDARD\r")?;
for property in &self.0 {
write!(f, "{}", property)?;
}
writeln!(f, "END:STANDARD\r")
}
}
impl<'a> From<Standard<'a>> for Component<'a> {
fn from(component: Standard<'a>) -> Self {
Component {
name: "STANDARD".into(),
properties: component.0,
subcomponents: Vec::new()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Daylight<'a>(Vec<Property<'a>>);
impl<'a> Daylight<'a> {
pub fn new<S, T, F>(dtstart: S, tz_offset_from: F, tz_offset_to: T) -> Self
where
S: Into<Cow<'a, str>>,
F: Into<Cow<'a, str>>,
T: Into<Cow<'a, str>>
{
Daylight(vec![
DtStart::new(dtstart).into(),
TzOffsetFrom::new(tz_offset_from).into(),
TzOffsetTo::new(tz_offset_to).into(),
])
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.push(property.into());
}
}
impl<'a> fmt::Display for Daylight<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:DAYLIGHT\r")?;
for property in &self.0 {
write!(f, "{}", property)?;
}
writeln!(f, "END:DAYLIGHT\r")
}
}
impl<'a> From<Daylight<'a>> for Component<'a> {
fn from(component: Daylight<'a>) -> Self {
Component {
name: "DAYLIGHT".into(),
properties: component.0,
subcomponents: Vec::new()
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Alarm<'a>(Vec<Property<'a>>);
impl<'a> Alarm<'a> {
pub fn new(action: Action<'a>, trigger: Trigger<'a>) -> Self {
Alarm(vec![action.into(), trigger.into()])
}
pub fn audio(trigger: Trigger<'a>) -> Self {
Self::new(Action::audio(), trigger)
}
pub fn display(trigger: Trigger<'a>, description: Description<'a>) -> Self {
Alarm(vec![
Action::display().into(),
trigger.into(),
description.into(),
])
}
pub fn email(trigger: Trigger<'a>, description: Description<'a>, summary: Summary<'a>) -> Self {
Alarm(vec![
Action::email().into(),
trigger.into(),
description.into(),
summary.into(),
])
}
pub fn push<P>(&mut self, property: P)
where
P: Into<Property<'a>>
{
self.0.push(property.into());
}
}
impl<'a> fmt::Display for Alarm<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "BEGIN:VALARM\r")?;
for property in &self.0 {
write!(f, "{}", property)?;
}
writeln!(f, "END:VALARM\r")
}
}
impl<'a> From<Alarm<'a>> for Component<'a> {
fn from(component: Alarm<'a>) -> Self {
Component {
name: "VALARM".into(),
properties: component.0,
subcomponents: Vec::new()
}
}
}