Lines
94.76 %
Functions
66.67 %
Branches
100 %
use crate::model::property::RecurrenceDateTimesPropertyValue;
use crate::serialize::WriteModel;
use std::io::Write;
impl WriteModel for crate::model::property::ComponentProperty {
fn write_model<W: Write>(&self, writer: &mut W) -> anyhow::Result<()> {
use crate::model::property::ComponentProperty;
match self {
ComponentProperty::DateTimeStamp(property) => {
writer.write_all(b"DTSTAMP")?;
property.params.as_slice().write_model(writer)?;
writer.write_all(b":")?;
property.value.write_model(writer)?;
}
ComponentProperty::UniqueIdentifier(property) => {
writer.write_all(b"UID")?;
ComponentProperty::DateTimeStart(property) => {
writer.write_all(b"DTSTART")?;
ComponentProperty::Classification(property) => {
writer.write_all(b"CLASS")?;
ComponentProperty::DateTimeCreated(property) => {
writer.write_all(b"CREATED")?;
ComponentProperty::Description(property) => {
writer.write_all(b"DESCRIPTION")?;
ComponentProperty::GeographicPosition(property) => {
writer.write_all(b"GEO")?;
write!(writer, "{};", property.value.latitude)?;
write!(writer, "{}", property.value.longitude)?;
ComponentProperty::LastModified(property) => {
writer.write_all(b"LAST-MODIFIED")?;
ComponentProperty::Location(property) => {
writer.write_all(b"LOCATION")?;
ComponentProperty::Organizer(property) => {
writer.write_all(b"ORGANIZER")?;
writer.write_all(property.value.as_bytes())?;
ComponentProperty::Priority(property) => {
writer.write_all(b"PRIORITY")?;
write!(writer, "{}", property.value)?;
ComponentProperty::Sequence(property) => {
writer.write_all(b"SEQUENCE")?;
ComponentProperty::Summary(property) => {
writer.write_all(b"SUMMARY")?;
ComponentProperty::TimeTransparency(property) => {
writer.write_all(b"TRANSP")?;
ComponentProperty::RequestStatus(property) => {
writer.write_all(b"REQUEST-STATUS")?;
if let Some(code) = property.value.status_code.first() {
write!(writer, "{}", code)?;
for code in property.value.status_code.iter().skip(1) {
write!(writer, ".{}", code)?;
writer.write_all(b";")?;
writer.write_all(property.value.description.as_bytes())?;
if let Some(exception_data) = &property.value.exception_data {
writer.write_all(exception_data.as_bytes())?;
ComponentProperty::Url(property) => {
writer.write_all(b"URL")?;
ComponentProperty::RecurrenceId(property) => {
writer.write_all(b"RECURRENCE-ID")?;
ComponentProperty::RecurrenceRule(property) => {
writer.write_all(b"RRULE")?;
ComponentProperty::DateTimeEnd(property) => {
writer.write_all(b"DTEND")?;
ComponentProperty::Duration(property) => {
writer.write_all(b"DURATION")?;
ComponentProperty::Attach(property) => {
writer.write_all(b"ATTACH")?;
ComponentProperty::Attendee(property) => {
writer.write_all(b"ATTENDEE")?;
ComponentProperty::Categories(property) => {
writer.write_all(b"CATEGORIES")?;
if let Some(category) = property.value.first() {
category.write_model(writer)?;
for category in property.value.iter().skip(1) {
writer.write_all(b",")?;
ComponentProperty::Comment(property) => {
writer.write_all(b"COMMENT")?;
ComponentProperty::Contact(property) => {
writer.write_all(b"CONTACT")?;
ComponentProperty::ExceptionDateTimes(property) => {
writer.write_all(b"EXDATE")?;
if let Some(dt) = property.value.first() {
dt.write_model(writer)?;
for dt in property.value.iter().skip(1) {
ComponentProperty::Status(property) => {
writer.write_all(b"STATUS")?;
ComponentProperty::RelatedTo(property) => {
writer.write_all(b"RELATED-TO")?;
ComponentProperty::Resources(property) => {
writer.write_all(b"RESOURCES")?;
if let Some(resource) = property.value.first() {
resource.write_model(writer)?;
for resource in property.value.iter().skip(1) {
ComponentProperty::RecurrenceDateTimes(property) => {
writer.write_all(b"RDATE")?;
match &property.value {
RecurrenceDateTimesPropertyValue::DateTimes(date_times) => {
if let Some(dt) = date_times.first() {
for dt in date_times.iter().skip(1) {
RecurrenceDateTimesPropertyValue::Periods(periods) => {
if let Some(period) = periods.first() {
period.write_model(writer)?;
for period in periods.iter().skip(1) {
ComponentProperty::DateTimeCompleted(property) => {
writer.write_all(b"COMPLETED")?;
ComponentProperty::PercentComplete(property) => {
writer.write_all(b"PERCENT-COMPLETE")?;
ComponentProperty::DateTimeDue(property) => {
writer.write_all(b"DUE")?;
ComponentProperty::FreeBusyTime(property) => {
writer.write_all(b"FREEBUSY")?;
if let Some(period) = property.value.first() {
for period in property.value.iter().skip(1) {
ComponentProperty::TimeZoneId(property) => {
writer.write_all(b"TZID")?;
if property.value.unique_registry_id {
writer.write_all(b"/")?;
writer.write_all(property.value.id.as_bytes())?;
ComponentProperty::TimeZoneUrl(property) => {
writer.write_all(b"TZURL")?;
ComponentProperty::TimeZoneOffsetTo(property) => {
writer.write_all(b"TZOFFSETTO")?;
ComponentProperty::TimeZoneOffsetFrom(property) => {
writer.write_all(b"TZOFFSETFROM")?;
ComponentProperty::TimeZoneName(property) => {
writer.write_all(b"TZNAME")?;
ComponentProperty::Action(property) => {
writer.write_all(b"ACTION")?;
ComponentProperty::Trigger(property) => {
writer.write_all(b"TRIGGER")?;
crate::model::property::TriggerValue::Relative(duration) => {
duration.write_model(writer)?;
crate::model::property::TriggerValue::Absolute(date_time) => {
date_time.write_model(writer)?;
ComponentProperty::Repeat(property) => {
writer.write_all(b"REPEAT")?;
ComponentProperty::IanaProperty(property) => {
writer.write_all(property.name.as_bytes())?;
ComponentProperty::XProperty(property) => {
Ok(())
impl WriteModel for &[crate::model::param::Param] {
for param in self.iter() {
param.write_model(writer)?;