diff options
-rw-r--r-- | src/dav/calencoder.rs | 87 | ||||
-rw-r--r-- | src/dav/caltypes.rs | 40 |
2 files changed, 94 insertions, 33 deletions
diff --git a/src/dav/calencoder.rs b/src/dav/calencoder.rs index a701fe1..ca314f1 100644 --- a/src/dav/calencoder.rs +++ b/src/dav/calencoder.rs @@ -470,61 +470,124 @@ impl<C: CalContext> QuickWritable<C> for Expand { impl<C: CalContext> QuickWritable<C> for LimitRecurrenceSet { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + let mut empty = ctx.create_cal_element("limit-recurrence-set"); + empty.push_attribute(("start", format!("{}", self.0.format(ICAL_DATETIME_FMT)).as_str())); + empty.push_attribute(("end", format!("{}", self.1.format(ICAL_DATETIME_FMT)).as_str())); + xml.write_event_async(Event::Empty(empty)).await } } impl<C: CalContext> QuickWritable<C> for LimitFreebusySet { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + let mut empty = ctx.create_cal_element("limit-freebusy-set"); + empty.push_attribute(("start", format!("{}", self.0.format(ICAL_DATETIME_FMT)).as_str())); + empty.push_attribute(("end", format!("{}", self.1.format(ICAL_DATETIME_FMT)).as_str())); + xml.write_event_async(Event::Empty(empty)).await } } impl<C: CalContext> QuickWritable<C> for CalendarSelector<C> { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + match self { + Self::AllProp => xml.write_event_async(Event::Empty(ctx.create_dav_element("allprop"))).await, + Self::PropName => xml.write_event_async(Event::Empty(ctx.create_dav_element("propname"))).await, + Self::Prop(prop) => prop.write(xml, ctx).await, + } } } impl<C: CalContext> QuickWritable<C> for CompFilter { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + let mut start = ctx.create_cal_element("comp-filter"); + start.push_attribute(("name", self.name.as_str())); + + match &self.additional_rules { + None => xml.write_event_async(Event::Empty(start)).await, + Some(rules) => { + let end = start.to_end(); + + xml.write_event_async(Event::Start(start.clone())).await?; + rules.write(xml, ctx.child()).await?; + xml.write_event_async(Event::End(end)).await + } + } } } -impl<C: CalContext> QuickWritable<C> for CompFilterInner { +impl<C: CalContext> QuickWritable<C> for CompFilterRules { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + match self { + Self::IsNotDefined => xml.write_event_async(Event::Empty(ctx.create_dav_element("is-not-defined"))).await, + Self::Matches(cfm) => cfm.write(xml, ctx).await, + } } } impl<C: CalContext> QuickWritable<C> for CompFilterMatch { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + if let Some(time_range) = &self.time_range { + time_range.write(xml, ctx.child()).await?; + } + + for prop_item in self.prop_filter.iter() { + prop_item.write(xml, ctx.child()).await?; + } + for comp_item in self.comp_filter.iter() { + // Required: recursion in an async fn requires boxing + // rustc --explain E0733 + Box::pin(comp_item.write(xml, ctx.child())).await?; + } + Ok(()) } } impl<C: CalContext> QuickWritable<C> for PropFilter { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + let mut start = ctx.create_cal_element("prop-filter"); + start.push_attribute(("name", self.name.as_str())); + + match &self.additional_rules { + None => xml.write_event_async(Event::Empty(start)).await, + Some(rules) => { + let end = start.to_end(); + xml.write_event_async(Event::Start(start.clone())).await?; + rules.write(xml, ctx.child()).await?; + xml.write_event_async(Event::End(end)).await + } + } } } -impl<C: CalContext> QuickWritable<C> for PropFilterInner { +impl<C: CalContext> QuickWritable<C> for PropFilterRules { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + match self { + Self::IsNotDefined => xml.write_event_async(Event::Empty(ctx.create_dav_element("is-not-defined"))).await, + Self::Match(prop_match) => prop_match.write(xml, ctx).await, + } } } impl<C: CalContext> QuickWritable<C> for PropFilterMatch { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + if let Some(time_range) = &self.time_range { + time_range.write(xml, ctx.child()).await?; + } + if let Some(time_or_text) = &self.time_or_text { + time_or_text.write(xml, ctx.child()).await?; + } + for param_item in self.param_filter.iter() { + param_item.write(xml, ctx.child()).await?; + } + Ok(()) } } impl<C: CalContext> QuickWritable<C> for TimeOrText { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { - unimplemented!(); + match self { + Self::Time(time) => time.write(xml, ctx).await, + Self::Text(txt) => txt.write(xml, ctx).await, + } } } diff --git a/src/dav/caltypes.rs b/src/dav/caltypes.rs index 5668201..e2ba490 100644 --- a/src/dav/caltypes.rs +++ b/src/dav/caltypes.rs @@ -1028,7 +1028,7 @@ pub struct Expand(pub DateTime<Utc>, pub DateTime<Utc>); /// end CDATA #REQUIRED> /// start value: an iCalendar "date with UTC time" /// end value: an iCalendar "date with UTC time" -pub struct LimitRecurrenceSet(DateTime<Utc>, DateTime<Utc>); +pub struct LimitRecurrenceSet(pub DateTime<Utc>, pub DateTime<Utc>); /// Name: limit-freebusy-set /// @@ -1058,7 +1058,7 @@ pub struct LimitRecurrenceSet(DateTime<Utc>, DateTime<Utc>); /// end CDATA #REQUIRED> /// start value: an iCalendar "date with UTC time" /// end value: an iCalendar "date with UTC time" -pub struct LimitFreebusySet(DateTime<Utc>, DateTime<Utc>); +pub struct LimitFreebusySet(pub DateTime<Utc>, pub DateTime<Utc>); /// Used by CalendarQuery & CalendarMultiget pub enum CalendarSelector<T: Dav::Extension> { @@ -1116,21 +1116,20 @@ pub enum CalendarSelector<T: Dav::Extension> { /// name value: a calendar object or calendar component /// type (e.g., VEVENT) pub struct CompFilter { - name: Component, - inner: CompFilterInner, + pub name: Component, + // Option 1 = None, Option 2, 3, 4 = Some + pub additional_rules: Option<CompFilterRules>, } -pub enum CompFilterInner { - // Option 1 - Empty, +pub enum CompFilterRules { // Option 2 IsNotDefined, // Options 3 & 4 Matches(CompFilterMatch), } pub struct CompFilterMatch { - time_range: Option<TimeRange>, - prop_filter: Vec<PropFilter>, - comp_filter: Vec<CompFilter>, + pub time_range: Option<TimeRange>, + pub prop_filter: Vec<PropFilter>, + pub comp_filter: Vec<CompFilter>, } /// Name: prop-filter @@ -1178,21 +1177,20 @@ pub struct CompFilterMatch { /// <!ATTLIST prop-filter name CDATA #REQUIRED> /// name value: a calendar property name (e.g., ATTENDEE) pub struct PropFilter { - name: Component, - inner: PropFilterInner, + pub name: Component, + // None = Option 1, Some() = Option 2, 3 & 4 + pub additional_rules: Option<PropFilterRules>, } -pub enum PropFilterInner { - // Option 1 - Empty, +pub enum PropFilterRules { // Option 2 IsNotDefined, // Options 3 & 4 Match(PropFilterMatch), } pub struct PropFilterMatch { - time_range: Option<TimeRange>, - time_or_text: Option<TimeOrText>, - param_filter: Vec<ParamFilter>, + pub time_range: Option<TimeRange>, + pub time_or_text: Option<TimeOrText>, + pub param_filter: Vec<ParamFilter>, } pub enum TimeOrText { Time(TimeRange), @@ -1228,9 +1226,9 @@ pub enum TimeOrText { /// <!ATTLIST text-match collation CDATA "i;ascii-casemap" /// negate-condition (yes | no) "no"> pub struct TextMatch { - collation: Option<Collation>, - negate_condition: bool, - text: String, + pub collation: Option<Collation>, + pub negate_condition: Option<bool>, + pub text: String, } /// Name: param-filter |