diff options
author | Malte Brandy <malte.brandy@maralorn.de> | 2018-04-18 18:04:40 +0200 |
---|---|---|
committer | Malte Brandy <malte.brandy@maralorn.de> | 2018-04-19 10:50:19 +0200 |
commit | bb1f2315354e4c788f4aa817dcc330619cfcb932 (patch) | |
tree | c471ba980405e02ea64796e38c02cf6ee832e3fb | |
parent | 7d71d84d619005c68f395ea2f00eb404ed365a79 (diff) |
Make everything work with recent serde
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | examples/create_task.rs | 27 | ||||
-rw-r--r-- | src/lib.rs | 6 | ||||
-rw-r--r-- | src/task.rs | 349 | ||||
-rw-r--r-- | src/uda.rs | 91 |
5 files changed, 254 insertions, 221 deletions
@@ -24,7 +24,7 @@ serde = "1" serde_derive = "1" serde_json = "1" uuid = { version = "0.6", features = ["serde"] } +log = "0.4" [dev-dependencies] env_logger = "0.4" - diff --git a/examples/create_task.rs b/examples/create_task.rs index b7eafca..c79d417 100644 --- a/examples/create_task.rs +++ b/examples/create_task.rs @@ -5,6 +5,7 @@ extern crate uuid; use task_hookrs::task::Task; use task_hookrs::status::TaskStatus; +use task_hookrs::uda::UDA; use chrono::NaiveDateTime; use serde_json::to_string; @@ -13,7 +14,29 @@ use uuid::Uuid; fn main() { let uuid = Uuid::nil(); let date = NaiveDateTime::parse_from_str("2016-12-31 12:13:14", "%Y-%m-%d %H:%M:%S").unwrap(); - let t = Task::new(TaskStatus::Pending, uuid, date.into(), "Test task".to_string(), - None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,); + let t = Task::new( + Some(12), + TaskStatus::Pending, + uuid, + date.into(), + "Test task".to_string(), + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + UDA::default(), + ); println!("[{}]", to_string(&t).unwrap()); } @@ -46,12 +46,16 @@ extern crate chrono; extern crate serde; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; extern crate serde_json; extern crate uuid; #[cfg(test)] extern crate env_logger; +#[cfg(test)] +#[macro_use] +extern crate log; pub mod annotation; pub mod date; diff --git a/src/task.rs b/src/task.rs index 187b146..5114d83 100644 --- a/src/task.rs +++ b/src/task.rs @@ -7,14 +7,16 @@ //! Module containing `Task` type as well as trait implementations use std::result::Result as RResult; -use std::collections::BTreeMap; +use std::fmt; use serde::Serialize; use serde::Serializer; +use serde::ser::SerializeStruct; use serde::Deserialize; use serde::Deserializer; use serde::de::Visitor; -use serde::de::MapVisitor as DeserializeMapVisitor; +use serde::de::Error; +use serde::de::MapAccess; use uuid::Uuid; use priority::TaskPriority; @@ -41,30 +43,30 @@ use uda::{UDA, UDAName, UDAValue}; /// tasks is simply serializing and deserializing objects of this type. #[derive(Debug, Clone)] pub struct Task { - id : Option<u64>, - - status : TaskStatus, - uuid : Uuid, - entry : Date, - description : String, - annotations : Option<Vec<Annotation>>, - depends : Option<String>, - due : Option<Date>, - end : Option<Date>, - imask : Option<i64>, - mask : Option<String>, - modified : Option<Date>, - parent : Option<Uuid>, - priority : Option<TaskPriority>, - project : Option<Project>, - recur : Option<String>, - scheduled : Option<Date>, - start : Option<Date>, - tags : Option<Vec<Tag>>, - until : Option<Date>, - wait : Option<Date>, - - uda : UDA, + id: Option<u64>, + + status: TaskStatus, + uuid: Uuid, + entry: Date, + description: String, + annotations: Option<Vec<Annotation>>, + depends: Option<String>, + due: Option<Date>, + end: Option<Date>, + imask: Option<i64>, + mask: Option<String>, + modified: Option<Date>, + parent: Option<Uuid>, + priority: Option<TaskPriority>, + project: Option<Project>, + recur: Option<String>, + scheduled: Option<Date>, + start: Option<Date>, + tags: Option<Vec<Tag>>, + until: Option<Date>, + wait: Option<Date>, + + uda: UDA, } /* @@ -341,94 +343,79 @@ impl Task { pub fn uda(&self) -> &UDA { &self.uda } - /// Get the BTreeMap that contains the UDA mutable - pub fn uda(&mut self) -> &mut UDA { - &self.uda + pub fn uda_mut(&mut self) -> &mut UDA { + &mut self.uda + } } impl Serialize for Task { - - fn serialize<S>(&self, serializer: &mut S) -> RResult<(), S::Error> - where S: Serializer + fn serialize<S>(&self, serializer: S) -> RResult<S::Ok, S::Error> + where + S: Serializer, { - let mut state = try!(serializer.serialize_struct("Task", 19)); - try!(serializer.serialize_struct_elt(&mut state, "id", self.id)); - try!(serializer.serialize_struct_elt(&mut state, "status", &self.status)); - try!(serializer.serialize_struct_elt(&mut state, "uuid", &self.uuid)); - try!(serializer.serialize_struct_elt(&mut state, "entry", &self.entry)); - try!(serializer.serialize_struct_elt(&mut state, "description", &self.description)); - try!(serializer.serialize_struct_elt(&mut state, "annotations", &self.annotations)); - try!(serializer.serialize_struct_elt(&mut state, "tags", &self.tags)); - - match self.recur { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "recur", v)), - None => { }, - } - match self.depends { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "depends", v)), - None => { }, - } - match self.due { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "due", v)), - None => { }, - } - match self.end { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "end", v)), - None => { }, - } - match self.imask { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "imask", v)), - None => { }, - } - match self.mask { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "mask", v)), - None => { }, - } - match self.modified { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "modified", v)), - None => { }, - } - match self.parent { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "parent", v)), - None => { }, - } - match self.priority { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "priority", v)), - None => { }, - } - match self.project { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "project", v)), - None => { }, - } - match self.scheduled { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "scheduled", v)), - None => { }, - } - match self.start { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "start", v)), - None => { }, - } - match self.until { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "until", v)), - None => { }, - } - match self.wait { - Some(ref v) => try!(serializer.serialize_struct_elt(&mut state, "wait", v)), - None => { }, - } + let mut state = serializer.serialize_struct("Task", 19)?; + state.serialize_field("id", &self.id)?; + state.serialize_field("status", &self.status)?; + state.serialize_field("uuid", &self.uuid)?; + state.serialize_field("entry", &self.entry)?; + state.serialize_field("description", &self.description)?; + state.serialize_field("annotations", &self.annotations)?; + state.serialize_field("tags", &self.tags)?; + + self.recur.as_ref().map( + |ref v| state.serialize_field("recur", v), + ); + self.depends.as_ref().map(|ref v| { + state.serialize_field("depends", v) + }); + self.due.as_ref().map( + |ref v| state.serialize_field("due", v), + ); + self.end.as_ref().map( + |ref v| state.serialize_field("end", v), + ); + self.imask.as_ref().map( + |ref v| state.serialize_field("imask", v), + ); + self.mask.as_ref().map( + |ref v| state.serialize_field("mask", v), + ); + self.modified.as_ref().map(|ref v| { + state.serialize_field("modified", v) + }); + self.parent.as_ref().map(|ref v| { + state.serialize_field("parent", v) + }); + self.priority.as_ref().map(|ref v| { + state.serialize_field("priority", v) + }); + self.project.as_ref().map(|ref v| { + state.serialize_field("project", v) + }); + self.scheduled.as_ref().map(|ref v| { + state.serialize_field("scheduled", v) + }); + self.start.as_ref().map( + |ref v| state.serialize_field("start", v), + ); + self.until.as_ref().map( + |ref v| state.serialize_field("until", v), + ); + self.wait.as_ref().map( + |ref v| state.serialize_field("wait", v), + ); - try!(serializer.serialize_struct_elt(&mut state, "uda", &self.uda)); + state.serialize_field("uda", &self.uda)?; - serializer.serialize_struct_end(state) + state.end() } - } -impl Deserialize for Task { - - fn deserialize<D>(deserializer: &mut D) -> RResult<Task, D::Error> - where D: Deserializer +impl<'de> Deserialize<'de> for Task { + fn deserialize<D>(deserializer: D) -> RResult<Task, D::Error> + where + D: Deserializer<'de>, { static FIELDS: &'static [&'static str] = &[ "id", @@ -453,49 +440,53 @@ impl Deserialize for Task { "tags", "until", "wait", - "uda" + "uda", ]; deserializer.deserialize_struct("Task", FIELDS, TaskDeserializeVisitor) } - } /// Helper type for task deserialization struct TaskDeserializeVisitor; -impl Visitor for TaskDeserializeVisitor { +impl<'de> Visitor<'de> for TaskDeserializeVisitor { type Value = Task; - fn visit_map<V>(&mut self, mut visitor: V) -> RResult<Task, V::Error> - where V: DeserializeMapVisitor + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "A dictionary containing task properties") + } + + fn visit_map<V>(self, mut visitor: V) -> RResult<Task, V::Error> + where + V: MapAccess<'de>, { - let mut id = None; + let mut id = None; - let mut status = None; - let mut uuid = None; - let mut entry = None; + let mut status = None; + let mut uuid = None; + let mut entry = None; let mut description = None; let mut annotations = None; - let mut depends = None; - let mut due = None; - let mut end = None; - let mut imask = None; - let mut mask = None; - let mut modified = None; - let mut parent = None; - let mut priority = None; - let mut project = None; - let mut recur = None; - let mut scheduled = None; - let mut start = None; - let mut tags = None; - let mut until = None; - let mut wait = None; - let mut uda = UDA::default(); + let mut depends = None; + let mut due = None; + let mut end = None; + let mut imask = None; + let mut mask = None; + let mut modified = None; + let mut parent = None; + let mut priority = None; + let mut project = None; + let mut recur = None; + let mut scheduled = None; + let mut start = None; + let mut tags = None; + let mut until = None; + let mut wait = None; + let mut uda = UDA::default(); loop { - let key : Option<String> = try!(visitor.visit_key()); + let key: Option<String> = visitor.next_key()?; if key.is_none() { break; } @@ -503,74 +494,74 @@ impl Visitor for TaskDeserializeVisitor { match &key[..] { "id" => { - id = Some(try!(visitor.visit_value())); - }, + id = Some(try!(visitor.next_value())); + } "status" => { - status = Some(try!(visitor.visit_value())); - }, + status = Some(visitor.next_value()?); + } "uuid" => { - uuid = Some(try!(visitor.visit_value())); - }, + uuid = Some(try!(visitor.next_value())); + } "entry" => { - entry = Some(try!(visitor.visit_value())); - }, + entry = Some(try!(visitor.next_value())); + } "description" => { - description = Some(try!(visitor.visit_value())); - }, + description = Some(try!(visitor.next_value())); + } "annotations" => { - annotations = Some(try!(visitor.visit_value())); - }, + annotations = Some(try!(visitor.next_value())); + } "depends" => { - depends = Some(try!(visitor.visit_value())); - }, + depends = Some(try!(visitor.next_value())); + } "due" => { - due = Some(try!(visitor.visit_value())); - }, + due = Some(try!(visitor.next_value())); + } "end" => { - end = Some(try!(visitor.visit_value())); - }, + end = Some(try!(visitor.next_value())); + } "imask" => { - imask = Some(try!(visitor.visit_value())); - }, + imask = Some(try!(visitor.next_value())); + } "mask" => { - mask = Some(try!(visitor.visit_value())); - }, + mask = Some(try!(visitor.next_value())); + } "modified" => { - modified = Some(try!(visitor.visit_value())); - }, + modified = Some(try!(visitor.next_value())); + } "parent" => { - parent = Some(try!(visitor.visit_value())); - }, + parent = Some(try!(visitor.next_value())); + } "priority" => { - priority = Some(try!(visitor.visit_value())); - }, + priority = Some(try!(visitor.next_value())); + } "project" => { - project = Some(try!(visitor.visit_value())); - }, + project = Some(try!(visitor.next_value())); + } "recur" => { - recur = Some(try!(visitor.visit_value())); - }, + recur = Some(try!(visitor.next_value())); + } "scheduled" => { - scheduled = Some(try!(visitor.visit_value())); - }, + scheduled = Some(try!(visitor.next_value())); + } "start" => { - start = Some(try!(visitor.visit_value())); - }, + start = Some(try!(visitor.next_value())); + } "tags" => { - tags = Some(try!(visitor.visit_value())); - }, + tags = Some(try!(visitor.next_value())); + } "until" => { - until = Some(try!(visitor.visit_value())); - }, + until = Some(try!(visitor.next_value())); + } "wait" => { - wait = Some(try!(visitor.visit_value())); - }, + wait = Some(try!(visitor.next_value())); + } field => { - debug!("Inserting '{}' as UDA", field); - let uda_value : UDAValue = try!(visitor.visit_value()); + eprintln!("Inserting '{}' as UDA", field); + let uda_value: UDAValue = try!(visitor.next_value()); uda.insert(UDAName::from(field), uda_value); } } @@ -578,26 +569,24 @@ impl Visitor for TaskDeserializeVisitor { let status = match status { Some(status) => status, - None => try!(visitor.missing_field("status")), + None => Err(V::Error::missing_field("status"))?, }; let uuid = match uuid { Some(uuid) => uuid, - None => try!(visitor.missing_field("uuid")), + None => Err(V::Error::missing_field("uuid"))?, }; let entry = match entry { Some(entry) => entry, - None => try!(visitor.missing_field("entry")), + None => Err(V::Error::missing_field("entry"))?, }; let description = match description { Some(description) => description, - None => try!(visitor.missing_field("description")), + None => Err(V::Error::missing_field("description"))?, }; - try!(visitor.end()); - let task = Task::new( id, status, @@ -4,64 +4,63 @@ use std::ops::{Deref, DerefMut}; use std::default::Default; use std::collections::BTreeMap; use std::result::Result as RResult; +use std::fmt; use serde::Serialize; use serde::Serializer; use serde::Deserialize; use serde::Deserializer; +use serde::de::Visitor; +use serde::de; /// UDA Name #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct UDAName(String); impl<'a> From<&'a str> for UDAName { - fn from(s: &str) -> UDAName { UDAName(String::from(s)) } - } - impl From<String> for UDAName { - fn from(s: String) -> UDAName { UDAName(s) } - } impl Serialize for UDAName { - - fn serialize<S>(&self, serializer: &mut S) -> RResult<(), S::Error> - where S: Serializer + fn serialize<S>(&self, serializer: S) -> RResult<S::Ok, S::Error> + where + S: Serializer, { self.0.serialize(serializer) } - } -impl Deserialize for UDAName { - - fn deserialize<D>(deserializer: &mut D) -> RResult<UDAName, D::Error> - where D: Deserializer +impl<'de> Deserialize<'de> for UDAName { + fn deserialize<D>(deserializer: D) -> RResult<UDAName, D::Error> + where + D: Deserializer<'de>, { String::deserialize(deserializer).map(|s| UDAName(s)) } - } /// UDA Value #[derive(Clone, Debug, PartialEq, PartialOrd)] pub enum UDAValue { + /// UDA is a string Str(String), + /// UDA is an integer U64(u64), + /// UDA is a float F64(f64), } impl Serialize for UDAValue { - - fn serialize<S>(&self, serializer: &mut S) -> RResult<(), S::Error> - where S: Serializer + fn serialize<S>(&self, serializer: S) -> RResult<S::Ok, S::Error> + where + S: Serializer, { match self { &UDAValue::Str(ref s) => s.serialize(serializer), @@ -69,17 +68,43 @@ impl Serialize for UDAValue { &UDAValue::F64(s) => s.serialize(serializer), } } - } -impl Deserialize for UDAValue { +struct UDAVisitor; - fn deserialize<D>(deserializer: &mut D) -> RResult<UDAValue, D::Error> - where D: Deserializer +impl<'de> Visitor<'de> for UDAVisitor { + type Value = UDAValue; + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an UDA value like a string, float or int") + } + + fn visit_u64<E>(self, value: u64) -> Result<UDAValue, E> + where + E: de::Error, + { + Ok(UDAValue::U64(value)) + } + fn visit_f64<E>(self, value: f64) -> Result<UDAValue, E> + where + E: de::Error, { - unimplemented!() + Ok(UDAValue::F64(value)) } + fn visit_str<E>(self, value: &str) -> Result<UDAValue, E> + where + E: de::Error, + { + Ok(UDAValue::Str(value.to_owned())) + } +} +impl<'de> Deserialize<'de> for UDAValue { + fn deserialize<D>(deserializer: D) -> RResult<UDAValue, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(UDAVisitor) + } } /// Wrapper type for BTreeMap<UDAName, UDAValue> so serde does not automatically implement the @@ -93,42 +118,34 @@ impl Deref for UDA { fn deref(&self) -> &BTreeMap<UDAName, UDAValue> { &self.0 } - } impl DerefMut for UDA { - fn deref_mut(&mut self) -> &mut BTreeMap<UDAName, UDAValue> { &mut self.0 } - } impl Default for UDA { - fn default() -> UDA { UDA(BTreeMap::new()) } - } impl Serialize for UDA { - - fn serialize<S>(&self, serializer: &mut S) -> RResult<(), S::Error> - where S: Serializer + fn serialize<S>(&self, serializer: S) -> RResult<S::Ok, S::Error> + where + S: Serializer, { self.0.serialize(serializer) } - } -impl Deserialize for UDA { - - fn deserialize<D>(deserializer: &mut D) -> RResult<UDA, D::Error> - where D: Deserializer +impl<'de> Deserialize<'de> for UDA { + fn deserialize<D>(deserializer: D) -> RResult<UDA, D::Error> + where + D: Deserializer<'de>, { BTreeMap::deserialize(deserializer).map(|btm| UDA(btm)) } - } - |