Unhandled lines from iCal files are stored
This commit is contained in:
+46
-21
@@ -5,7 +5,11 @@ use std::error::Error;
|
||||
use chrono::{DateTime, Utc};
|
||||
use ics::properties::{Completed, Created, LastModified, PercentComplete, Status, Summary};
|
||||
use ics::{ICalendar, ToDo};
|
||||
use ics::components::Parameter as IcsParameter;
|
||||
use ics::components::Property as IcsProperty;
|
||||
use ical::property::Property as IcalProperty;
|
||||
|
||||
use crate::Task;
|
||||
use crate::item::Item;
|
||||
use crate::task::CompletionStatus;
|
||||
use crate::settings::{ORG_NAME, PRODUCT_NAME};
|
||||
@@ -16,37 +20,43 @@ fn ical_product_id() -> String {
|
||||
|
||||
/// Create an iCal item from a `crate::item::Item`
|
||||
pub fn build_from(item: &Item) -> Result<String, Box<dyn Error>> {
|
||||
let s_last_modified = format_date_time(item.last_modified());
|
||||
match item {
|
||||
Item::Task(t) => build_from_task(t),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_from_task(task: &Task) -> Result<String, Box<dyn Error>> {
|
||||
let s_last_modified = format_date_time(task.last_modified());
|
||||
|
||||
let mut todo = ToDo::new(
|
||||
item.uid(),
|
||||
task.uid(),
|
||||
s_last_modified.clone(),
|
||||
);
|
||||
|
||||
item.creation_date().map(|dt|
|
||||
task.creation_date().map(|dt|
|
||||
todo.push(Created::new(format_date_time(dt)))
|
||||
);
|
||||
todo.push(LastModified::new(s_last_modified));
|
||||
todo.push(Summary::new(item.name()));
|
||||
todo.push(Summary::new(task.name()));
|
||||
|
||||
match item {
|
||||
Item::Task(t) => {
|
||||
match t.completion_status() {
|
||||
CompletionStatus::Uncompleted => {
|
||||
todo.push(Status::needs_action());
|
||||
},
|
||||
CompletionStatus::Completed(completion_date) => {
|
||||
todo.push(PercentComplete::new("100"));
|
||||
completion_date.as_ref().map(|dt| todo.push(
|
||||
Completed::new(format_date_time(dt))
|
||||
));
|
||||
todo.push(Status::completed());
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
unimplemented!()
|
||||
match task.completion_status() {
|
||||
CompletionStatus::Uncompleted => {
|
||||
todo.push(Status::needs_action());
|
||||
},
|
||||
CompletionStatus::Completed(completion_date) => {
|
||||
todo.push(PercentComplete::new("100"));
|
||||
completion_date.as_ref().map(|dt| todo.push(
|
||||
Completed::new(format_date_time(dt))
|
||||
));
|
||||
todo.push(Status::completed());
|
||||
}
|
||||
}
|
||||
|
||||
// Also add fields that we have not handled
|
||||
for ical_property in task.extra_parameters() {
|
||||
let ics_property = ical_to_ics_property(ical_property.clone());
|
||||
todo.push(ics_property);
|
||||
}
|
||||
|
||||
let mut calendar = ICalendar::new("2.0", ical_product_id());
|
||||
@@ -60,6 +70,21 @@ fn format_date_time(dt: &DateTime<Utc>) -> String {
|
||||
}
|
||||
|
||||
|
||||
fn ical_to_ics_property(prop: IcalProperty) -> IcsProperty<'static> {
|
||||
let mut ics_prop = match prop.value {
|
||||
Some(value) => IcsProperty::new(prop.name, value),
|
||||
None => IcsProperty::new(prop.name, ""),
|
||||
};
|
||||
prop.params.map(|v| {
|
||||
for (key, vec_values) in v {
|
||||
let values = vec_values.join(";");
|
||||
ics_prop.add(IcsParameter::new(key, values));
|
||||
}
|
||||
});
|
||||
ics_prop
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
+5
-2
@@ -36,6 +36,8 @@ pub fn parse(content: &str, item_id: ItemId, sync_status: SyncStatus) -> Result<
|
||||
let mut last_modified = None;
|
||||
let mut completion_date = None;
|
||||
let mut creation_date = None;
|
||||
let mut extra_parameters = Vec::new();
|
||||
|
||||
for prop in &todo.properties {
|
||||
match prop.name.as_str() {
|
||||
"SUMMARY" => { name = prop.value.clone() },
|
||||
@@ -67,7 +69,8 @@ pub fn parse(content: &str, item_id: ItemId, sync_status: SyncStatus) -> Result<
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// This field is not supported.
|
||||
// This field is not supported. Let's store it anyway, so that we are able to re-create an identical iCal file
|
||||
extra_parameters.push(prop.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +96,7 @@ pub fn parse(content: &str, item_id: ItemId, sync_status: SyncStatus) -> Result<
|
||||
true => CompletionStatus::Completed(completion_date),
|
||||
};
|
||||
|
||||
Item::Task(Task::new_with_parameters(name, uid, item_id, completion_status, sync_status, creation_date, last_modified))
|
||||
Item::Task(Task::new_with_parameters(name, uid, item_id, completion_status, sync_status, creation_date, last_modified, extra_parameters))
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user