From 94a134c44eebe7fa09121dbc5f91e82a29bd9898 Mon Sep 17 00:00:00 2001 From: Francesco Guardiani Date: Tue, 4 Aug 2020 08:26:18 +0200 Subject: [PATCH] Refactored iterator methods of Event (#66) * Refactored a bit the iterator entry point Signed-off-by: Francesco Guardiani * cargo fmt Signed-off-by: Francesco Guardiani --- src/event/attributes.rs | 19 ++++++++++++++++- src/event/event.rs | 45 +++++++++++++++++++++++++++++++--------- tests/attributes_iter.rs | 4 ++-- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/event/attributes.rs b/src/event/attributes.rs index 43f55d4..de7a019 100644 --- a/src/event/attributes.rs +++ b/src/event/attributes.rs @@ -1,19 +1,34 @@ use super::{ - AttributesIntoIteratorV03, AttributesIntoIteratorV10, AttributesV03, AttributesV10, SpecVersion, + AttributesIntoIteratorV03, AttributesIntoIteratorV10, AttributesV03, AttributesV10, + ExtensionValue, SpecVersion, }; use chrono::{DateTime, Utc}; +use serde::Serializer; use std::fmt; use url::Url; +/// Value of a CloudEvent attribute #[derive(Debug, PartialEq)] pub enum AttributeValue<'a> { SpecVersion(SpecVersion), String(&'a str), URI(&'a Url), URIRef(&'a Url), + Boolean(&'a bool), + Integer(&'a i64), Time(&'a DateTime), } +impl<'a> From<&'a ExtensionValue> for AttributeValue<'a> { + fn from(ev: &'a ExtensionValue) -> Self { + match ev { + ExtensionValue::String(s) => AttributeValue::String(s), + ExtensionValue::Boolean(b) => AttributeValue::Boolean(b), + ExtensionValue::Integer(i) => AttributeValue::Integer(i), + } + } +} + impl fmt::Display for AttributeValue<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -22,6 +37,8 @@ impl fmt::Display for AttributeValue<'_> { AttributeValue::URI(s) => f.write_str(&s.as_str()), AttributeValue::URIRef(s) => f.write_str(&s.as_str()), AttributeValue::Time(s) => f.write_str(&s.to_rfc3339()), + AttributeValue::Boolean(b) => f.serialize_bool(**b), + AttributeValue::Integer(i) => f.serialize_i64(**i), } } } diff --git a/src/event/event.rs b/src/event/event.rs index 8fe2dcb..4e6b7dd 100644 --- a/src/event/event.rs +++ b/src/event/event.rs @@ -78,14 +78,27 @@ impl Default for Event { } impl Event { - /// Returns an [`Iterator`] for [`Attributes`] - pub fn attributes_iter<'a>(&'a self) -> impl Iterator)> { + /// Returns an [`Iterator`] for all the available [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes) and extensions. + /// Same as chaining [`Event::iter_attributes()`] and [`Event::iter_extensions()`] + pub fn iter(&self) -> impl Iterator { + self.iter_attributes() + .chain(self.extensions.iter().map(|(k, v)| (k.as_str(), v.into()))) + } + + /// Returns an [`Iterator`] for all the available [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes), excluding extensions. + /// This iterator does not contain the `data` field. + pub fn iter_attributes(&self) -> impl Iterator { match &self.attributes { Attributes::V03(a) => AttributesIter::IterV03(a.into_iter()), Attributes::V10(a) => AttributesIter::IterV10(a.into_iter()), } } + /// Get all the [extensions](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) + pub fn iter_extensions(&self) -> impl Iterator { + self.extensions.iter().map(|(k, v)| (k.as_str(), v)) + } + /// Remove `data`, `dataschema` and `datacontenttype` from this `Event` pub fn remove_data(&mut self) { self.data = None; @@ -166,14 +179,6 @@ impl Event { self.extensions.get(extension_name) } - /// Get all the [extensions](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) - pub fn get_extensions(&self) -> Vec<(&str, &ExtensionValue)> { - self.extensions - .iter() - .map(|(k, v)| (k.as_str(), v)) - .collect() - } - /// Set the [extension](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) named `extension_name` with `extension_value` pub fn set_extension<'name, 'event: 'name>( &'event mut self, @@ -235,4 +240,24 @@ mod tests { assert!(e.get_dataschema().is_none()); assert!(e.get_datacontenttype().is_none()); } + + #[test] + fn iter() { + let mut e = Event::default(); + e.set_extension("aaa", "bbb"); + e.write_data( + "application/json", + serde_json::json!({ + "hello": "world" + }), + ); + + let mut v: HashMap<&str, AttributeValue> = e.iter().collect(); + + assert_eq!( + v.remove("specversion"), + Some(AttributeValue::SpecVersion(SpecVersion::V10)) + ); + assert_eq!(v.remove("aaa"), Some(AttributeValue::String("bbb"))) + } } diff --git a/tests/attributes_iter.rs b/tests/attributes_iter.rs index 4722c47..d7d8c6e 100644 --- a/tests/attributes_iter.rs +++ b/tests/attributes_iter.rs @@ -6,7 +6,7 @@ use test_data::*; #[test] fn iter_v10_test() { let in_event = v10::full_no_data(); - let mut iter_v10 = in_event.attributes_iter(); + let mut iter_v10 = in_event.iter_attributes(); assert_eq!( ("specversion", AttributeValue::SpecVersion(SpecVersion::V10)), @@ -17,7 +17,7 @@ fn iter_v10_test() { #[test] fn iter_v03_test() { let in_event = v03::full_json_data(); - let mut iter_v03 = in_event.attributes_iter(); + let mut iter_v03 = in_event.iter_attributes(); assert_eq!( ("specversion", AttributeValue::SpecVersion(SpecVersion::V03)),