summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-04-16 20:04:57 +0200
committerMarkus Unterwaditzer <markus@unterwaditzer.net>2018-04-16 20:04:57 +0200
commit034710fe9784836a3dde5060d13fd99e31e322fc (patch)
tree29b39efb1cc1f662f0854f1c48a3064a0efb29d2
parent05c58c3b3c68baf982cbd058b5bd2865296c56f6 (diff)
Rewrite icalendar API for nice builder pattern style building of objects (#22)
-rw-r--r--src/util.rs48
-rw-r--r--src/vcard.rs113
2 files changed, 95 insertions, 66 deletions
diff --git a/src/util.rs b/src/util.rs
index f414ed7..6802e69 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -45,54 +45,6 @@ macro_rules! create_data_type {
}
}
-macro_rules! make_builder_fn {
- (
- fn $fnname:ident building $property_name:tt with_params,
- $mapfn:expr => $( $arg_name:ident : $arg_type:ty ),*
- ) => {
- pub fn $fnname(mut self, params: $crate::param::Parameters, $( $arg_name : $arg_type ),*) -> Self {
- let raw_value = vec![ $( $arg_name ),* ]
- .into_iter()
- .map($mapfn)
- .collect::<Vec<_>>()
- .join(";");
-
- let prop = Property {
- name: String::from($property_name),
- params: params,
- raw_value: raw_value,
- prop_group: None
- };
-
- self.0.props.entry(String::from($property_name)).or_insert(vec![]).push(prop);
- self
- }
- };
-
- (
- fn $fnname:ident building $property_name:tt,
- $mapfn:expr => $( $arg_name:ident : $arg_type:ty ),*
- ) => {
- pub fn $fnname(mut self, $( $arg_name : $arg_type ),*) -> Self {
- let raw_value = vec![ $( $arg_name ),* ]
- .into_iter()
- .map($mapfn)
- .collect::<Vec<_>>()
- .join(";");
-
-
- let prop = Property {
- name: String::from($property_name),
- params: BTreeMap::new(),
- raw_value: raw_value,
- prop_group: None
- };
- self.0.props.entry(String::from($property_name)).or_insert(vec![]).push(prop);
- self
- }
- }
-}
-
#[cfg(feature = "timeconversions")]
pub const DATE_TIME_FMT : &'static str = "%Y%m%dT%H%M%SZ";
diff --git a/src/vcard.rs b/src/vcard.rs
index 4191adc..a989d19 100644
--- a/src/vcard.rs
+++ b/src/vcard.rs
@@ -33,6 +33,11 @@ impl Vcard {
})
}
+ /// Helper for `VcardBuilder::new()`
+ pub fn builder() -> VcardBuilder {
+ VcardBuilder::new()
+ }
+
/// Wrap a Component into a Vcard object, or don't do it if the Component is not a Vcard.
pub fn from_component(c: Component)-> RResult<Vcard, Component> {
if c.name == "VCARD" {
@@ -73,6 +78,92 @@ impl Vcard {
make_getter_function_for_values!(url , "URL" , Url);
make_getter_function_for_optional!(version , "VERSION" , Version);
+ fn set_properties(&mut self, props: BTreeMap<String, Vec<Property>>) {
+ self.0.props = props;
+ }
+
+}
+
+impl Default for Vcard {
+ fn default() -> Self {
+ Vcard(Component::new(String::from("VCARD")))
+ }
+}
+
+impl Deref for Vcard {
+ type Target = Component;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+/// A builder for building a Vcard object.
+pub struct VcardBuilder {
+ properties: BTreeMap<String, Vec<Property>>
+}
+
+macro_rules! make_builder_fn {
+ (
+ fn $fnname:ident building $property_name:tt with_params,
+ $mapfn:expr => $( $arg_name:ident : $arg_type:ty ),*
+ ) => {
+ pub fn $fnname(mut self, params: $crate::param::Parameters, $( $arg_name : $arg_type ),*) -> Self {
+ let raw_value = vec![ $( $arg_name ),* ]
+ .into_iter()
+ .map($mapfn)
+ .collect::<Vec<_>>()
+ .join(";");
+
+ let prop = Property {
+ name: String::from($property_name),
+ params: params,
+ raw_value: raw_value,
+ prop_group: None
+ };
+
+ self.properties.entry(String::from($property_name)).or_insert(vec![]).push(prop);
+ self
+ }
+ };
+
+ (
+ fn $fnname:ident building $property_name:tt,
+ $mapfn:expr => $( $arg_name:ident : $arg_type:ty ),*
+ ) => {
+ pub fn $fnname(mut self, $( $arg_name : $arg_type ),*) -> Self {
+ let raw_value = vec![ $( $arg_name ),* ]
+ .into_iter()
+ .map($mapfn)
+ .collect::<Vec<_>>()
+ .join(";");
+
+
+ let prop = Property {
+ name: String::from($property_name),
+ params: BTreeMap::new(),
+ raw_value: raw_value,
+ prop_group: None
+ };
+ self.properties.entry(String::from($property_name)).or_insert(vec![]).push(prop);
+ self
+ }
+ }
+}
+
+impl VcardBuilder {
+ pub fn new() -> Self {
+ VcardBuilder {
+ properties: BTreeMap::new(),
+ }
+ }
+
+ pub fn build(self) -> Result<Vcard> {
+ let mut v = Vcard::default();
+ v.set_properties(self.properties);
+ Ok(v)
+ }
+
make_builder_fn!(fn with_adr building "ADR" with_params,
|o| o.unwrap_or(String::from("")) =>
pobox : Option<String>,
@@ -123,20 +214,6 @@ impl Vcard {
}
-impl Default for Vcard {
- fn default() -> Self {
- Vcard(Component::new(String::from("VCARD")))
- }
-}
-
-impl Deref for Vcard {
- type Target = Component;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
create_data_type!(Adr);
create_data_type!(Anniversary);
create_data_type!(BDay);
@@ -213,8 +290,6 @@ impl Name {
}
-pub struct VcardBuilder(Component);
-
#[cfg(test)]
mod test {
use super::Vcard;
@@ -249,7 +324,7 @@ mod test {
fn test_vcard_builder() {
use component::write_component;
- let build = Vcard::default()
+ let build = Vcard::builder()
.with_name(parameters!(),
None,
Some("Mustermann".into()),
@@ -270,7 +345,9 @@ mod test {
Some("51147".into()),
Some("Deutschland".into()))
.with_email("erika@mustermann.de".into())
- .with_rev("20140301T221110Z".into());
+ .with_rev("20140301T221110Z".into())
+ .build()
+ .unwrap();
let build_string = write_component(&build);