diff --git a/src/ical/parser.rs b/src/ical/parser.rs index c60c7c1..31aa34f 100644 --- a/src/ical/parser.rs +++ b/src/ical/parser.rs @@ -29,10 +29,20 @@ pub fn parse(content: &str, item_id: ItemId, sync_status: SyncStatus) -> Result< CurrentType::Todo(todo) => { let mut name = None; + let mut completed = false; for prop in &todo.properties { if prop.name == "SUMMARY" { name = prop.value.clone(); - break; + } + if prop.name == "STATUS" { + // Possible values: + // "NEEDS-ACTION" ;Indicates to-do needs action. + // "COMPLETED" ;Indicates to-do completed. + // "IN-PROCESS" ;Indicates to-do in process of. + // "CANCELLED" ;Indicates to-do was cancelled. + if prop.value.as_ref().map(|s| s.as_str()) == Some("COMPLETED") { + completed = true; + } } } let name = match name { @@ -40,7 +50,7 @@ pub fn parse(content: &str, item_id: ItemId, sync_status: SyncStatus) -> Result< None => return Err(format!("Missing name for item {}", item_id).into()), }; - Item::Task(Task::new(name, item_id, sync_status)) + Item::Task(Task::new(name, item_id, sync_status, completed)) }, }; @@ -96,6 +106,22 @@ DTSTAMP:20210321T001600 SUMMARY:Do not forget to do this END:VTODO END:VCALENDAR +"#; + + const EXAMPLE_ICAL_COMPLETED: &str = r#"BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Nextcloud Tasks v0.13.6 +BEGIN:VTODO +UID:0633de27-8c32-42be-bcb8-63bc879c6185 +CREATED:20210321T001600 +LAST-MODIFIED:20210402T081557 +DTSTAMP:20210402T081557 +SUMMARY:Clean up your room or Mom will be angry +PERCENT-COMPLETE:100 +COMPLETED:20210402T081557 +STATUS:COMPLETED +END:VTODO +END:VCALENDAR "#; const EXAMPLE_MULTIPLE_ICAL: &str = r#"BEGIN:VCALENDAR @@ -138,6 +164,18 @@ END:VCALENDAR assert_eq!(task.sync_status(), &sync_status); } + #[test] + fn test_ical_completion_parsing() { + let version_tag = VersionTag::from(String::from("test-tag")); + let sync_status = SyncStatus::Synced(version_tag); + let item_id: ItemId = "http://some.id/for/testing".parse().unwrap(); + + let item = parse(EXAMPLE_ICAL_COMPLETED, item_id.clone(), sync_status.clone()).unwrap(); + let task = item.unwrap_task(); + + assert_eq!(task.completed(), true); + } + #[test] fn test_multiple_items_in_ical() { let version_tag = VersionTag::from(String::from("test-tag")); diff --git a/src/task.rs b/src/task.rs index db22ebd..21a620e 100644 --- a/src/task.rs +++ b/src/task.rs @@ -20,12 +20,12 @@ pub struct Task { impl Task { /// Create a new Task - pub fn new(name: String, id: ItemId, sync_status: SyncStatus) -> Self { + pub fn new(name: String, id: ItemId, sync_status: SyncStatus, completed: bool) -> Self { Self { id, name, sync_status, - completed: false, + completed, } } @@ -66,8 +66,6 @@ impl Task { /// Set the completion status pub fn set_completed(&mut self, new_value: bool) { - // TODO: either require a reference to the DataSource, so that it is aware - // or change a flag here, and the DataSource will be able to check the flags of all its content (but then the Calendar should only give a reference/Arc, not a clone) self.update_sync_status(); self.completed = new_value; }