Skip to content

Commit

Permalink
Test a simple vevent property
Browse files Browse the repository at this point in the history
  • Loading branch information
ThetaSinner committed May 25, 2024
1 parent bf0d21b commit a791f2e
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 15 deletions.
163 changes: 160 additions & 3 deletions src/parser/component/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
use crate::parser::object::types::{CalendarComponent, ComponentProperty};
use crate::parser::property::{prop_date_time_stamp, prop_date_time_start, prop_iana, prop_x};
use crate::parser::property::{
prop_attach, prop_attendee, prop_categories, prop_classification, prop_comment, prop_contact,
prop_created, prop_date_time_end, prop_date_time_stamp, prop_date_time_start, prop_description,
prop_duration, prop_exception_date_times, prop_geographic_position, prop_iana,
prop_last_modified, prop_location, prop_organizer, prop_priority, prop_recurrence_date_times,
prop_recurrence_id, prop_recurrence_rule, prop_related_to, prop_request_status, prop_resources,
prop_sequence, prop_status, prop_summary, prop_time_transparency, prop_unique_identifier,
prop_url, prop_x,
};
use crate::parser::Error;
use nom::branch::alt;
use nom::bytes::streaming::tag;
Expand All @@ -11,8 +19,40 @@ pub fn component_event(input: &[u8]) -> IResult<&[u8], CalendarComponent, Error>
let (input, (_, properties, _)) = tuple((
tag("BEGIN:VEVENT\r\n"),
many0(alt((
prop_date_time_start.map(ComponentProperty::DateTimeStart),
prop_date_time_stamp.map(ComponentProperty::DateTimeStamp),
alt((
prop_date_time_stamp.map(ComponentProperty::DateTimeStamp),
prop_unique_identifier.map(ComponentProperty::UniqueIdentifier),
prop_date_time_start.map(ComponentProperty::DateTimeStart),
prop_classification.map(ComponentProperty::Classification),
prop_created.map(ComponentProperty::DateTimeCreated),
prop_description.map(ComponentProperty::Description),
prop_geographic_position.map(ComponentProperty::GeographicPosition),
prop_last_modified.map(ComponentProperty::LastModified),
prop_location.map(ComponentProperty::Location),
prop_organizer.map(ComponentProperty::Organizer),
prop_priority.map(ComponentProperty::Priority),
prop_sequence.map(ComponentProperty::Sequence),
prop_status.map(ComponentProperty::Status),
prop_summary.map(ComponentProperty::Summary),
prop_time_transparency.map(ComponentProperty::TimeTransparency),
)),
alt((
prop_url.map(ComponentProperty::Url),
prop_recurrence_id.map(ComponentProperty::RecurrenceId),
prop_recurrence_rule.map(ComponentProperty::RecurrenceRule),
prop_date_time_end.map(ComponentProperty::DateTimeEnd),
prop_duration.map(ComponentProperty::Duration),
prop_attach.map(ComponentProperty::Attach),
prop_attendee.map(ComponentProperty::Attendee),
prop_categories.map(ComponentProperty::Categories),
prop_comment.map(ComponentProperty::Comment),
prop_contact.map(ComponentProperty::Contact),
prop_exception_date_times.map(ComponentProperty::ExceptionDateTimes),
prop_request_status.map(ComponentProperty::RequestStatus),
prop_related_to.map(ComponentProperty::RelatedTo),
prop_resources.map(ComponentProperty::Resources),
prop_recurrence_date_times.map(ComponentProperty::RecurrenceDateTimes),
)),
prop_x.map(ComponentProperty::XProp),
prop_iana.map(ComponentProperty::IanaProp),
))),
Expand All @@ -21,3 +61,120 @@ pub fn component_event(input: &[u8]) -> IResult<&[u8], CalendarComponent, Error>

Ok((input, CalendarComponent::Event { properties }))
}

#[cfg(test)]
mod tests {
use super::*;
use crate::parser::property::{
CategoriesProperty, Classification, ClassificationProperty, Date, DateOrDateTime, DateTime,
DateTimeEndProperty, DateTimeStamp, DateTimeStartProperty, SummaryProperty, Time,
UniqueIdentifierProperty,
};
use crate::test_utils::check_rem;

#[test]
fn test_component_event() {
let input = b"BEGIN:VEVENT\r\nUID:[email protected]\r\nDTSTAMP:19970901T130000Z\r\nDTSTART:19970903T163000Z\r\nDTEND:19970903T190000Z\r\nSUMMARY:Annual Employee Review\r\nCLASS:PRIVATE\r\nCATEGORIES:BUSINESS,HUMAN RESOURCES\r\nEND:VEVENT\r\n";
let (rem, component) = component_event(input).unwrap();
check_rem(rem, 0);

match component {
CalendarComponent::Event { properties } => {
assert_eq!(properties.len(), 7);

assert_eq!(
properties[0],
ComponentProperty::UniqueIdentifier(UniqueIdentifierProperty {
other_params: vec![],
value: b"[email protected]".to_vec(),
})
);

assert_eq!(
properties[1],
ComponentProperty::DateTimeStamp(DateTimeStamp {
other_params: vec![],
value: DateTime {
date: Date {
year: 1997,
month: 9,
day: 1,
},
time: Time {
hour: 13,
minute: 0,
second: 0,
is_utc: true,
},
},
})
);

assert_eq!(
properties[2],
ComponentProperty::DateTimeStart(DateTimeStartProperty {
params: vec![],
value: DateOrDateTime::DateTime(DateTime {
date: Date {
year: 1997,
month: 9,
day: 3,
},
time: Time {
hour: 16,
minute: 30,
second: 0,
is_utc: true,
},
}),
})
);

assert_eq!(
properties[3],
ComponentProperty::DateTimeEnd(DateTimeEndProperty {
params: vec![],
value: DateOrDateTime::DateTime(DateTime {
date: Date {
year: 1997,
month: 9,
day: 3,
},
time: Time {
hour: 19,
minute: 0,
second: 0,
is_utc: true,
},
}),
})
);

assert_eq!(
properties[4],
ComponentProperty::Summary(SummaryProperty {
params: vec![],
value: b"Annual Employee Review".to_vec(),
})
);

assert_eq!(
properties[5],
ComponentProperty::Classification(ClassificationProperty {
other_params: vec![],
value: Classification::Private,
})
);

assert_eq!(
properties[6],
ComponentProperty::Categories(CategoriesProperty {
params: vec![],
value: vec![b"BUSINESS".to_vec(), b"HUMAN RESOURCES".to_vec()],
})
);
}
_ => panic!("Unexpected component type"),
}
}
}
42 changes: 39 additions & 3 deletions src/parser/object/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
use crate::parser::property::types::{
CalendarScaleProperty, IanaProperty, MethodProperty, ProductId, VersionProperty, XProperty,
};
use crate::parser::property::{DateTimeStamp, DateTimeStartProperty};
use crate::parser::property::{
AttachProperty, AttendeeProperty, CategoriesProperty, ClassificationProperty, CommentProperty,
ContactProperty, CreatedProperty, DateTimeEndProperty, DateTimeStamp, DateTimeStartProperty,
DescriptionProperty, DurationProperty, ExceptionDateTimesProperty, GeographicPositionProperty,
LastModifiedProperty, LocationProperty, OrganizerProperty, PriorityProperty,
RecurrenceDateTimesProperty, RecurrenceIdProperty, RecurrenceRuleProperty, RelatedToProperty,
RequestStatusProperty, ResourcesProperty, SequenceProperty, StatusProperty, SummaryProperty,
TimeTransparencyProperty, UniqueIdentifierProperty, UrlProperty,
};
use crate::parser::ContentLine;

#[derive(Debug)]
Expand All @@ -20,10 +28,38 @@ pub enum CalendarProperty<'a> {
IanaProp(IanaProperty<'a>),
}

#[derive(Debug, Eq, PartialEq)]
#[derive(Debug, PartialEq)]
pub enum ComponentProperty<'a> {
DateTimeStart(DateTimeStartProperty<'a>),
DateTimeStamp(DateTimeStamp<'a>),
UniqueIdentifier(UniqueIdentifierProperty<'a>),
DateTimeStart(DateTimeStartProperty<'a>),
Classification(ClassificationProperty<'a>),
DateTimeCreated(CreatedProperty<'a>),
Description(DescriptionProperty<'a>),
GeographicPosition(GeographicPositionProperty<'a>),
LastModified(LastModifiedProperty<'a>),
Location(LocationProperty<'a>),
Organizer(OrganizerProperty<'a>),
Priority(PriorityProperty<'a>),
Sequence(SequenceProperty<'a>),
Status(StatusProperty<'a>),
Summary(SummaryProperty<'a>),
TimeTransparency(TimeTransparencyProperty<'a>),
Url(UrlProperty<'a>),
RecurrenceId(RecurrenceIdProperty<'a>),
RecurrenceRule(RecurrenceRuleProperty<'a>),
DateTimeEnd(DateTimeEndProperty<'a>),
Duration(DurationProperty<'a>),
Attach(AttachProperty<'a>),
Attendee(AttendeeProperty<'a>),
Categories(CategoriesProperty<'a>),
Comment(CommentProperty<'a>),
Contact(ContactProperty<'a>),
ExceptionDateTimes(ExceptionDateTimesProperty<'a>),
RequestStatus(RequestStatusProperty<'a>),
RelatedTo(RelatedToProperty<'a>),
Resources(ResourcesProperty<'a>),
RecurrenceDateTimes(RecurrenceDateTimesProperty<'a>),
XProp(XProperty<'a>),
IanaProp(IanaProperty<'a>),
}
Expand Down
18 changes: 9 additions & 9 deletions src/parser/property/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ pub struct DescriptionProperty<'a> {
/// Parse a DESCRIPTION property.
///
/// RFC 5545, section 3.8.1.5
fn prop_description(input: &[u8]) -> IResult<&[u8], DescriptionProperty, Error> {
pub fn prop_description(input: &[u8]) -> IResult<&[u8], DescriptionProperty, Error> {
let (input, (_, params, _, value, _)) = tuple((
tag("DESCRIPTION"),
params,
Expand All @@ -191,7 +191,7 @@ pub struct GeographicPositionProperty<'a> {
/// Parse a GEO property.
///
/// RFC 5545, section 3.8.1.6
fn prop_geographic_position(input: &[u8]) -> IResult<&[u8], GeographicPositionProperty, Error> {
pub fn prop_geographic_position(input: &[u8]) -> IResult<&[u8], GeographicPositionProperty, Error> {
let (input, (_, other_params, _, (latitude, _, longitude), _)) = tuple((
tag("GEO"),
other_params,
Expand Down Expand Up @@ -595,15 +595,15 @@ pub fn prop_url(input: &[u8]) -> IResult<&[u8], UrlProperty, Error> {
}

#[derive(Debug, Eq, PartialEq)]
pub struct UniqueIdentifier<'a> {
pub struct UniqueIdentifierProperty<'a> {
pub other_params: Vec<Param<'a>>,
pub value: Vec<u8>,
}

/// Parse a UID property.
///
/// RFC 5545, section 3.8.4.7
pub fn prop_unique_identifier(input: &[u8]) -> IResult<&[u8], UniqueIdentifier, Error> {
pub fn prop_unique_identifier(input: &[u8]) -> IResult<&[u8], UniqueIdentifierProperty, Error> {
let (input, (_, other_params, _, value, _)) = tuple((
tag("UID"),
other_params,
Expand All @@ -614,7 +614,7 @@ pub fn prop_unique_identifier(input: &[u8]) -> IResult<&[u8], UniqueIdentifier,

Ok((
input,
UniqueIdentifier {
UniqueIdentifierProperty {
other_params,
value,
},
Expand Down Expand Up @@ -711,7 +711,7 @@ pub struct CreatedProperty<'a> {
/// Parse a CREATED property.
///
/// RFC 5545, section 3.8.7.1
pub fn prop_date_time_created(input: &[u8]) -> IResult<&[u8], CreatedProperty, Error> {
pub fn prop_created(input: &[u8]) -> IResult<&[u8], CreatedProperty, Error> {
let (input, (_, other_params, _, value, _)) = tuple((
tag("CREATED"),
other_params,
Expand Down Expand Up @@ -1451,7 +1451,7 @@ RSVP to team leader."#
check_rem(rem, 1);
assert_eq!(
prop,
UniqueIdentifier {
UniqueIdentifierProperty {
other_params: vec![],
value: b"[email protected]".to_vec(),
}
Expand Down Expand Up @@ -1640,7 +1640,7 @@ RSVP to team leader."#

#[test]
fn created() {
let (rem, prop) = prop_date_time_created(b"CREATED:19980118T230000Z\r\n;").unwrap();
let (rem, prop) = prop_created(b"CREATED:19980118T230000Z\r\n;").unwrap();
check_rem(rem, 1);
assert_eq!(
prop,
Expand All @@ -1665,7 +1665,7 @@ RSVP to team leader."#

#[test]
fn date_time_stamp() {
let (rem, prop) = prop_date_time_created(b"CREATED:19960329T133000Z\r\n;").unwrap();
let (rem, prop) = prop_created(b"CREATED:19960329T133000Z\r\n;").unwrap();
check_rem(rem, 1);
assert_eq!(
prop,
Expand Down

0 comments on commit a791f2e

Please sign in to comment.