summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Unterwaditzer <markus@unterwaditzer.net>2016-11-15 20:07:29 +0100
committerMarkus Unterwaditzer <markus@unterwaditzer.net>2016-11-15 20:07:29 +0100
commitee10d38238f120c5fa85004b2b38431a34d47235 (patch)
tree1b4dc0df0c0d90c0d4904ba8b85105d4d5e91f0f
parentcb041f208a5dc9abd74199d54cbaaa805db2d9a6 (diff)
Refactor API
-rw-r--r--src/vobject/lib.rs49
-rw-r--r--tests/lib.rs26
2 files changed, 42 insertions, 33 deletions
diff --git a/src/vobject/lib.rs b/src/vobject/lib.rs
index b892fd9..999e865 100644
--- a/src/vobject/lib.rs
+++ b/src/vobject/lib.rs
@@ -66,36 +66,45 @@ impl Component {
}
}
- /// Retrieve one property (from many) by key. Returns `None` if nothing is found.
- pub fn single_prop(&self, key: &str) -> Option<&Property> {
- match self.props.get(key) {
- Some(x) => {
- match x.len() {
- 1 => Some(&x[0]),
- _ => None
- }
- },
- None => None
- }
+ /// Append the given property, preserve other same-named properties.
+ pub fn push(&mut self, prop: Property) {
+ self.props.entry(prop.name.clone()).or_insert_with(Vec::new).push(prop);
+ }
+
+ /// Set the given property, remove other same-named properties.
+ pub fn set(&mut self, prop: Property) {
+ self.props.insert(prop.name.clone(), vec![prop]);
}
- /// Retrieve a mutable vector of properties for this key. Creates one (and inserts it into the
- /// component) if none exists.
- pub fn all_props_mut<T: Into<String>>(&mut self, key: T) -> &mut Vec<Property> {
- match self.props.entry(key.into()) {
- Occupied(values) => values.into_mut(),
- Vacant(values) => values.insert(vec![])
+ /// Retrieve one property by key. Returns `None` if not exactly one property was found.
+ pub fn get_only<P: AsRef<str>>(&self, name: P) -> Option<&Property> {
+ match self.props.get(name.as_ref()) {
+ Some(x) if x.len() == 1 => Some(&x[0]),
+ _ => None
}
}
/// Retrieve properties by key. Returns an empty slice if key doesn't exist.
- pub fn all_props(&self, key: &str) -> &[Property] {
+ pub fn get_all<P: AsRef<str>>(&self, name: P) -> &[Property] {
static EMPTY: &'static [Property] = &[];
- match self.props.get(key) {
+ match self.props.get(name.as_ref()) {
Some(values) => &values[..],
None => EMPTY
}
}
+
+ /// Remove a single property.
+ pub fn pop<P: AsRef<str>>(&mut self, name: P) -> Option<Property> {
+ match self.props.get_mut(name.as_ref()) {
+ Some(values) => values.pop(),
+ None => None
+ }
+ }
+
+ /// Remove all properties
+ pub fn remove<P: AsRef<str>>(&mut self, name: P) -> Option<Vec<Property>> {
+ self.props.remove(name.as_ref())
+ }
}
impl FromStr for Component {
@@ -388,7 +397,7 @@ impl<'s> Parser<'s> {
break;
} else {
- component.all_props_mut(property.name.to_owned()).push(property);
+ component.push(property);
}
};
diff --git a/tests/lib.rs b/tests/lib.rs
index d5e4f24..165de00 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -24,10 +24,10 @@ fn test_vcard_basic() {
REV:20140301T221110Z\n\
END:VCARD\n\r\n\n").unwrap();
- assert_eq!(item.single_prop("FN").unwrap().raw_value, s!("Erika Mustermann"));
- assert_eq!(item.single_prop("N").unwrap().raw_value, s!("Mustermann;Erika"));
+ assert_eq!(item.get_only("FN").unwrap().raw_value, s!("Erika Mustermann"));
+ assert_eq!(item.get_only("N").unwrap().raw_value, s!("Mustermann;Erika"));
- let mut tel_values = item.all_props("TEL").iter().map(|x| &x.raw_value[..]);
+ let mut tel_values = item.get_all("TEL").iter().map(|x| &x.raw_value[..]);
assert_eq!(tel_values.next().unwrap(), s!("(0221) 9999123"));
assert_eq!(tel_values.next().unwrap(), s!("(0221) 1234567"));
assert!(tel_values.next().is_none());
@@ -48,9 +48,9 @@ fn test_line_cont() {
END:VCARD").unwrap();
assert_eq!(item.name, s!("VCARD"));
- assert_eq!(item.single_prop("TEL").unwrap().raw_value, s!("55554444"));
- assert_eq!(item.single_prop("N").unwrap().raw_value, s!("Nikdo;Nikdo=vic"));
- assert_eq!(item.single_prop("FN").unwrap().raw_value, s!("Alice;Alice=vic"));
+ assert_eq!(item.get_only("TEL").unwrap().raw_value, s!("55554444"));
+ assert_eq!(item.get_only("N").unwrap().raw_value, s!("Nikdo;Nikdo=vic"));
+ assert_eq!(item.get_only("FN").unwrap().raw_value, s!("Alice;Alice=vic"));
}
#[test]
@@ -74,13 +74,13 @@ fn test_icalendar_basic() {
END:VCALENDAR\n").unwrap();
assert_eq!(item.name, s!("VCALENDAR"));
- assert!(item.single_prop("LOCATION").is_none());
- assert!(item.single_prop("ORGANIZER").is_none());
+ assert!(item.get_only("LOCATION").is_none());
+ assert!(item.get_only("ORGANIZER").is_none());
let event = &item.subcomponents[0];
assert_eq!(event.name, s!("VEVENT"));
- assert!(event.single_prop("ORGANIZER").is_some());
- assert_eq!(event.single_prop("LOCATION").unwrap().raw_value, s!("Somewhere"));
+ assert!(event.get_only("ORGANIZER").is_some());
+ assert_eq!(event.get_only("LOCATION").unwrap().raw_value, s!("Somewhere"));
}
#[test]
@@ -95,7 +95,7 @@ fn test_icalendar_multline() {
END:VEVENT\n").unwrap();
assert_eq!(event.name, s!("VEVENT"));
- assert_eq!(event.single_prop("SUMMARY").unwrap().raw_value,
+ assert_eq!(event.get_only("SUMMARY").unwrap().raw_value,
s!("Important meeting"));
}
@@ -122,7 +122,7 @@ fn test_escaping() {
ORGANIZER;CN=\"Cott:n Eye Joe\":mailto:joe@joe.com\n\
END:VCALENDAR\n").unwrap();
assert_eq!(item.name, s!("VCALENDAR"));
- assert_eq!(item.single_prop("ORGANIZER").unwrap().raw_value, s!("mailto:joe@joe.com"));
+ assert_eq!(item.get_only("ORGANIZER").unwrap().raw_value, s!("mailto:joe@joe.com"));
}
#[test]
@@ -132,6 +132,6 @@ fn test_property_groups() {
foo.EMAIL;TYPE=INTERNET:foo@example.com\n\
foo.X-ACTUAL-TYPE:CUSTOM\n\
END:VCARD\n").unwrap();
- assert_eq!(item.single_prop("EMAIL").unwrap().prop_group, Some("foo".to_owned()));
+ assert_eq!(item.get_only("EMAIL").unwrap().prop_group, Some("foo".to_owned()));
}