Refactored iterator methods of Event (#66)

* Refactored a bit the iterator entry point

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>

* cargo fmt

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
This commit is contained in:
Francesco Guardiani 2020-08-04 08:26:18 +02:00 committed by GitHub
parent 25af32ee3a
commit 94a134c44e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 13 deletions

View File

@ -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<Utc>),
}
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),
}
}
}

View File

@ -78,14 +78,27 @@ impl Default for Event {
}
impl Event {
/// Returns an [`Iterator`] for [`Attributes`]
pub fn attributes_iter<'a>(&'a self) -> impl Iterator<Item = (&'a str, AttributeValue<'a>)> {
/// 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<Item = (&str, AttributeValue)> {
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<Item = (&str, AttributeValue)> {
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<Item = (&str, &ExtensionValue)> {
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")))
}
}

View File

@ -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)),