use std::result::Result as RResult; use std::collections::BTreeMap; use component::Component; use component::parse_component; use property::Property; use error::*; #[cfg(feature = "timeconversions")] use chrono::NaiveDateTime; #[cfg(feature = "timeconversions")] use chrono::NaiveDate; #[cfg(feature = "timeconversions")] use util::DATE_TIME_FMT; #[cfg(feature = "timeconversions")] use util::DATE_FMT; /// An ICalendar representing type #[derive(Debug)] pub struct ICalendar(Component); impl ICalendar { /// Parse a string to a ICalendar object /// /// Returns an error if the parsed text is not a ICalendar (that means that an error is /// returned also if this is a valid Vcard!) /// pub fn build(s: &str) -> Result { let c = parse_component(s)?; Self::from_component(c).map_err(|_| VObjectErrorKind::NotAnICalendar(s.to_owned())) } pub fn empty() -> ICalendar { let c = Component::new("VCALENDAR"); ICalendar(c) } /// Add an event to the calendar pub fn add_event(&mut self, builder: EventBuilder) { self.0.subcomponents.push(builder.into_component()) } /// Chainable variant of `ICalendar::add_event()`. pub fn with_event(mut self, builder: EventBuilder) -> Self { self.0.subcomponents.push(builder.into_component()); self } /// Wrap a Component into a Vcard object, or don't do it if the Component is not a Vcard. pub fn from_component(c: Component)-> RResult { if c.name == "VCALENDAR" { Ok(ICalendar(c)) } else { Err(c) } } /// Get an iterator over the events in this calendar /// /// The iterator creates Ok(&Event) instances on the fly, or Err(&Component) instances if the /// item cannot be parsed as an Event, not forgetting any data. /// /// # Getting actual objects /// /// For getting a Event-instance iterator from this, one can use this as follows: /// /// ``` /// # use std::collections::BTreeMap; /// # use vobject::component::Component; /// # use vobject::icalendar::Event; /// # use vobject::icalendar::ICalendar; /// # let icalendar = ICalendar::from_component(Component { /// # name: "VCALENDAR".to_owned(), /// # props: BTreeMap::new(), /// # subcomponents: vec![] /// # }).unwrap(); /// icalendar /// .events() /// .filter_map(Result::ok) /// .map(|ev| ev.clone()) /// .collect::>(); /// ``` /// pub fn events<'a>(&'a self) -> EventIterator<'a> { EventIterator::new(self.0.subcomponents.iter()) } make_getter_function_for_optional!(version, "VERSION", Version); make_getter_function_for_optional!(prodid, "PRODID", Prodid); } create_data_type!(Version); create_data_type!(Prodid); pub struct EventIterator<'a>(::std::slice::Iter<'a, Component>); impl<'a> EventIterator<'a> { fn new(i: ::std::slice::Iter<'a, Component>) -> EventIterator<'a> { EventIterator(i) } } impl<'a> Iterator for EventIterator<'a> { type Item = RResult, &'a Component>; fn next(&mut self) -> Option { self.0.next().map(Event::from_component) } } #[derive(Debug, Clone)] pub struct Event<'a>(&'a Component); impl<'a> Event<'a> { fn from_component(c: &'a Component) -> RResult, &'a Component> { if c.name == "VEVENT" { Ok(Event(c)) } else { Err(c) } } make_getter_function_for_optional!(dtend , "DTEND" , Dtend); make_getter_function_for_optional!(dtstart , "DTSTART" , Dtstart); make_getter_function_for_optional!(dtstamp , "DTSTAMP" , Dtstamp); make_getter_function_for_optional!(uid , "UID" , Uid); make_getter_function_for_optional!(description , "DESCRIPTION" , Description); make_getter_function_for_optional!(summary , "SUMMARY" , Summary); make_getter_function_for_optional!(url , "URL" , Url); make_getter_function_for_optional!(location , "LOCATION" , Location); make_getter_function_for_optional!(class , "CLASS" , Class); make_getter_function_for_optional!(categories , "CATEGORIES" , Categories); make_getter_function_for_optional!(transp , "TRANSP" , Transp); make_getter_function_for_optional!(rrule , "RRULE" , Rrule); pub fn build() -> EventBuilder { EventBuilder(Component::new(String::from("VEVENT"))) } } create_data_type!(Dtend); create_data_type!(Dtstart); create_data_type!(Dtstamp); create_data_type!(Uid); create_data_type!(Description); create_data_type!(Summary); create_data_type!(Url); create_data_type!(Location); create_data_type!(Class); create_data_type!(Categories); create_data_type!(Transp); create_data_type!(Rrule); #[cfg(feature = "timeconversions")] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] pub enum Time { Date(NaiveDate), DateTime(NaiveDateTime), } #[cfg(feature = "timeconversions")] pub trait AsDateTime { fn as_datetime(&self) -> Result