Skip to content
This repository has been archived by the owner on Aug 17, 2024. It is now read-only.

Fix newlines #56

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/ical_generator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate ical;

use std::fs::File;
use std::io::BufReader;
#[cfg(all(feature = "ical", feature = "generator"))]
use std::{fs::File, io::BufReader};

#[cfg(all(feature = "ical", feature = "generator"))]
fn main() {
Expand Down
45 changes: 24 additions & 21 deletions src/generator/event_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,23 +192,26 @@ mod should {
//let e = start.format(ICAL_DATE_FORMAT).to_string();
assert_eq!(
e,
"BEGIN:VEVENT\nUID:UID_@_test\nDTSTAMP;TZID=Europe/Berlin:20201201T120423\n\
DTSTART;TZID=Europe/Berlin:20201206T170000\n\
DURATION:PT2H45M0S\nEND:VEVENT\n"
"BEGIN:VEVENT\r\n\
UID:UID_@_test\r\n\
DTSTAMP;TZID=Europe/Berlin:20201201T120423\r\n\
DTSTART;TZID=Europe/Berlin:20201206T170000\r\n\
DURATION:PT2H45M0S\r\n\
END:VEVENT\r\n"
);
}

#[test]
fn build_whole_day_event() {
use generator::Emitter;
let expect = "BEGIN:VEVENT\n\
UID:20070423T123432Z-541111@example.com\n\
DTSTAMP:20070423T123432Z\n\
DTSTART;VALUE=DATE:20070628\n\
DTEND;VALUE=DATE:20070709\n\
SUMMARY:Festival International de Jazz de Montreal\n\
TRANSP:TRANSPARENT\n\
END:VEVENT\n\
let expect = "BEGIN:VEVENT\r\n\
UID:20070423T123432Z-541111@example.com\r\n\
DTSTAMP:20070423T123432Z\r\n\
DTSTART;VALUE=DATE:20070628\r\n\
DTEND;VALUE=DATE:20070709\r\n\
SUMMARY:Festival International de Jazz de Montreal\r\n\
TRANSP:TRANSPARENT\r\n\
END:VEVENT\r\n\
";
let event = IcalEventBuilder::tzid("America/Montreal")
.uid("20070423T123432Z-541111@example.com")
Expand All @@ -228,16 +231,16 @@ mod should {
#[test]
fn build_frequent_ical_event() {
use generator::Emitter;
let expect = "BEGIN:VEVENT\n\
UID:19970901T130000Z-123403@example.com\n\
DTSTAMP:19970901T130000Z\n\
DTSTART;VALUE=DATE:19971102\n\
RRULE:FREQ=YEARLY\n\
SUMMARY:Our Blissful Anniversary\n\
TRANSP:TRANSPARENT\n\
CLASS:CONFIDENTIAL\n\
CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION\n\
END:VEVENT\n\
let expect = "BEGIN:VEVENT\r\n\
UID:19970901T130000Z-123403@example.com\r\n\
DTSTAMP:19970901T130000Z\r\n\
DTSTART;VALUE=DATE:19971102\r\n\
RRULE:FREQ=YEARLY\r\n\
SUMMARY:Our Blissful Anniversary\r\n\
TRANSP:TRANSPARENT\r\n\
CLASS:CONFIDENTIAL\r\n\
CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION\r\n\
END:VEVENT\r\n\
";
let event = IcalEventBuilder::tzid("America/Montreal")
.uid("19970901T130000Z-123403@example.com")
Expand Down
22 changes: 11 additions & 11 deletions src/generator/ical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub(crate) fn split_line<T: Into<String>>(str: T) -> String {
let mut str = str.into();
let mut x = 75;
while x < str.len() {
str.insert_str(x, "\n ");
x += 76;
str.insert_str(x, "\r\n ");
x += 77;
}
str
}
Expand Down Expand Up @@ -78,11 +78,11 @@ mod should {

#[test]
fn split_long_line() {
let text = "The ability to return a type that is only specified by the trait it impleme\n \
nts is especially useful in the context closures and iterators, which we c\n \
over in Chapter 13. Closures and iterators create types that only the comp\n \
let text = "The ability to return a type that is only specified by the trait it impleme\r\n \
nts is especially useful in the context closures and iterators, which we c\r\n \
over in Chapter 13. Closures and iterators create types that only the comp\r\n \
iler knows or types that are very long to specify.";
assert_eq!(text, split_line(text.replace("\n ", "")));
assert_eq!(text, split_line(text.replace("\r\n ", "")));
}

#[test]
Expand Down Expand Up @@ -127,7 +127,7 @@ fn get_params(params: &Option<Vec<(String, Vec<String>)>>) -> String {

impl Emitter for Property {
fn generate(&self) -> String {
split_line(self.name.clone() + &get_params(&self.params) + &get_value(&self.value)) + "\n"
split_line(self.name.clone() + &get_params(&self.params) + &get_value(&self.value)) + "\r\n"
}
}

Expand All @@ -140,29 +140,29 @@ impl Emitter for IcalTimeZoneTransition {
};
String::from("BEGIN:")
+ key
+ "\n"
+ "\r\n"
+ &self
.properties
.iter()
.map(Emitter::generate)
.collect::<String>()
+ "END:"
+ key
+ "\n"
+ "\r\n"
}
}

macro_rules! generate_emitter {
($struct:ident, $key:literal, $($prop:ident),+) => {
impl Emitter for $struct {
fn generate(&self) -> String {
let mut text = String::from("BEGIN:") + $key + "\n";
let mut text = String::from("BEGIN:") + $key + "\r\n";
$(text += &self.$prop
.iter()
.map(Emitter::generate)
.collect::<String>();)+

text + "END:" + $key + "\n"
text + "END:" + $key + "\r\n"
}
}
};
Expand Down
48 changes: 24 additions & 24 deletions src/generator/vcard_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,24 @@ mod should {
#[test]
fn build_vcards_wikipedia_example() {
use generator::Emitter;
let expect = "BEGIN:VCARD\n\
VERSION:4.0\n\
N:Gump;Forrest;;Mr.;\n\
FN:Forrest Gump\n\
ORG:Bubba Gump Shrimp Co.\n\
TITLE:Shrimp Man\n\
PHOTO;MEDIATYPE=image/gif:http://www.example.com/dir_photos/my_photo.gif\n\
TEL;TYPE=work,voice;VALUE=uri:tel:+1-111-555-1212\n\
TEL;TYPE=home,voice;VALUE=uri:tel:+1-404-555-1212\n\
ADR;TYPE=WORK;PREF=1;LABEL=\"100 Waters Edge\\nBaytown\\, LA 30314\\nUnited Sta\n \
tes of America\":;;100 Waters Edge;Baytown;LA;30314;United States of Americ\n \
a\n\
ADR;TYPE=HOME;LABEL=\"42 Plantation St.\\nBaytown\\, LA 30314\\nUnited States o\n f \
America\":;;42 Plantation St.;Baytown;LA;30314;United States of America\n\
EMAIL:forrestgump@example.com\n\
REV:20080424T195243Z\n\
x-qq:21588891\n\
END:VCARD\n\
let expect = "BEGIN:VCARD\r\n\
VERSION:4.0\r\n\
N:Gump;Forrest;;Mr.;\r\n\
FN:Forrest Gump\r\n\
ORG:Bubba Gump Shrimp Co.\r\n\
TITLE:Shrimp Man\r\n\
PHOTO;MEDIATYPE=image/gif:http://www.example.com/dir_photos/my_photo.gif\r\n\
TEL;TYPE=work,voice;VALUE=uri:tel:+1-111-555-1212\r\n\
TEL;TYPE=home,voice;VALUE=uri:tel:+1-404-555-1212\r\n\
ADR;TYPE=WORK;PREF=1;LABEL=\"100 Waters Edge\\nBaytown\\, LA 30314\\nUnited Sta\r\n \
tes of America\":;;100 Waters Edge;Baytown;LA;30314;United States of Americ\r\n \
a\r\n\
ADR;TYPE=HOME;LABEL=\"42 Plantation St.\\nBaytown\\, LA 30314\\nUnited States o\r\n f \
America\":;;42 Plantation St.;Baytown;LA;30314;United States of America\r\n\
EMAIL:forrestgump@example.com\r\n\
REV:20080424T195243Z\r\n\
x-qq:21588891\r\n\
END:VCARD\r\n\
";

let vcard = IcalVcardBuilder::version("4.0")
Expand Down Expand Up @@ -245,12 +245,12 @@ mod should {
#[test]
fn build_vcard_with_fn_generated() {
use generator::Emitter;
let expect = "BEGIN:VCARD\n\
VERSION:4.0\n\
N:Marx;Adolph;Arthur;Mr.;\n\
FN:Mr. Adolph Arthur Marx\n\
NICKNAME:Harpo Marx\n\
END:VCARD\n\
let expect = "BEGIN:VCARD\r\n\
VERSION:4.0\r\n\
N:Marx;Adolph;Arthur;Mr.;\r\n\
FN:Mr. Adolph Arthur Marx\r\n\
NICKNAME:Harpo Marx\r\n\
END:VCARD\r\n\
";
let vcard = IcalVcardBuilder::version("4.0")
.names(
Expand Down
9 changes: 2 additions & 7 deletions src/parser/ical/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,19 +313,14 @@ impl Component for IcalTimeZone {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))]
pub enum IcalTimeZoneTransitionType {
#[default]
STANDARD,
DAYLIGHT,
}

impl Default for IcalTimeZoneTransitionType {
fn default() -> Self {
IcalTimeZoneTransitionType::STANDARD
}
}

#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))]
pub struct IcalTimeZoneTransition {
Expand Down
27 changes: 25 additions & 2 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,29 @@ pub mod parser {
}
}

#[test]
// same as ical_example_1 but with \r\n endings instead of \n.
fn ical_example_2() {
let input = BufReader::new(File::open("./tests/ressources/ical_example_2.ics").unwrap());

let valids = std::fs::read_to_string("./tests/ressources/ical_example_2.res")
.unwrap()
.replace('\n', "");

let reader = ical::IcalParser::new(input);

for res in reader {
let calendar = match res {
Ok(res) => res,
Err(err) => panic!("{}", err),
};

let output = format!("{:?}", calendar);

assert_eq!(output, valids);
}
}

#[test]
fn vcard() {
let input = BufReader::new(File::open("./tests/ressources/vcard_input.vcf").unwrap());
Expand Down Expand Up @@ -219,7 +242,7 @@ pub mod generator {

let original = BufReader::new(File::open(filename).unwrap())
.lines()
.map(|line| line.unwrap() + "\n")
.map(|line| line.unwrap() + "\r\n")
.collect::<String>();

let input = BufReader::new(File::open(filename).unwrap());
Expand All @@ -235,7 +258,7 @@ pub mod generator {

let original = BufReader::new(File::open(filename).unwrap())
.lines()
.map(|line| line.unwrap() + "\n")
.map(|line| line.unwrap() + "\r\n")
.collect::<String>();

let input = BufReader::new(File::open(filename).unwrap());
Expand Down
47 changes: 47 additions & 0 deletions tests/ressources/ical_example_2.ics
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VTIMEZONE
TZID:W. Europe Standard Time
BEGIN:STANDARD
DTSTART:16011028T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010325T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
CREATED:20210511T063845Z
DESCRIPTION:Einwahldaten folgen in der Veranstaltungswoche \nSeminartitel:
Software-QS-Cast - Application Performance Monitoring\nDatum: 27.Mai 2021\
nUhrzeit: 10:30 - ca.12:00 Uhr \n \n
DTEND;TZID="W. Europe Standard Time":20210527T120000
DTSTAMP:20210511T063845Z
DTSTART;TZID="W. Europe Standard Time":20210527T103000
LAST-MODIFIED:20210511T063845Z
PRIORITY:5
SEQUENCE:0
SUMMARY;LANGUAGE=de:Software-QS-Cast Application Performance Monitoring
TRANSP:OPAQUE
UID:040000008200E000*************00800000000*****************00000000000000
010000000********************************
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-CONFTYPE:0
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR
35 changes: 35 additions & 0 deletions tests/ressources/ical_example_2.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
IcalCalendar {
properties: [
Property { name: "PRODID", params: None, value: Some("-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN") },
Property { name: "VERSION", params: None, value: Some("2.0") },
Property { name: "METHOD", params: None, value: Some("PUBLISH") },
Property { name: "X-MS-OLK-FORCEINSPECTOROPEN", params: None, value: Some("TRUE") }],
events: [
IcalEvent { properties: [
Property { name: "CLASS", params: None, value: Some("PUBLIC") },
Property { name: "CREATED", params: None, value: Some("20210511T063845Z") },
Property { name: "DESCRIPTION", params: None, value: Some("Einwahldaten folgen in der Veranstaltungswoche \\nSeminartitel:Software-QS-Cast - Application Performance Monitoring\\nDatum: 27.Mai 2021\\nUhrzeit: 10:30 - ca.12:00 Uhr \\n \\n") },
Property { name: "DTEND", params: Some([("TZID", ["W. Europe Standard Time"])]), value: Some("20210527T120000") },
Property { name: "DTSTAMP", params: None, value: Some("20210511T063845Z") },
Property { name: "DTSTART", params: Some([("TZID", ["W. Europe Standard Time"])]), value: Some("20210527T103000") },
Property { name: "LAST-MODIFIED", params: None, value: Some("20210511T063845Z") },
Property { name: "PRIORITY", params: None, value: Some("5") }, Property { name: "SEQUENCE", params: None, value: Some("0") },
Property { name: "SUMMARY", params: Some([("LANGUAGE", ["de"])]), value: Some("Software-QS-Cast Application Performance Monitoring") },
Property { name: "TRANSP", params: None, value: Some("OPAQUE") },
Property { name: "UID", params: None, value: Some("040000008200E000*************00800000000*****************00000000000000010000000********************************") },
Property { name: "X-MICROSOFT-CDO-BUSYSTATUS", params: None, value: Some("BUSY") },
Property { name: "X-MICROSOFT-CDO-IMPORTANCE", params: None, value: Some("1") },
Property { name: "X-MICROSOFT-DISALLOW-COUNTER", params: None, value: Some("FALSE") },
Property { name: "X-MS-OLK-CONFTYPE", params: None, value: Some("0") }],
alarms: [
IcalAlarm { properties: [
Property { name: "TRIGGER", params: None, value: Some("-PT15M") },
Property { name: "ACTION", params: None, value: Some("DISPLAY") },
Property { name: "DESCRIPTION", params: None, value: Some("Reminder") }] }] }],
alarms: [], todos: [], journals: [], free_busys: [],
timezones: [IcalTimeZone { properties: [Property { name: "TZID", params: None, value: Some("W. Europe Standard Time") }],
transitions: [IcalTimeZoneTransition { transition: STANDARD, properties: [Property { name: "DTSTART", params: None, value: Some("16011028T030000") },
Property { name: "RRULE", params: None, value: Some("FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10") },
Property { name: "TZOFFSETFROM", params: None, value: Some("+0200") },
Property { name: "TZOFFSETTO", params: None, value: Some("+0100") }] },
IcalTimeZoneTransition { transition: DAYLIGHT, properties: [Property { name: "DTSTART", params: None, value: Some("16010325T020000") }, Property { name: "RRULE", params: None, value: Some("FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3") }, Property { name: "TZOFFSETFROM", params: None, value: Some("+0100") }, Property { name: "TZOFFSETTO", params: None, value: Some("+0200") }] }] }] }
Loading