Skip to content

Commit 6f5a767

Browse files
Removing serde-value (cloudevents#107)
* Removed serde_value Signed-off-by: Francesco Guardiani <[email protected]> * clippy + fix Signed-off-by: Francesco Guardiani <[email protected]> * cargo fmt Signed-off-by: Francesco Guardiani <[email protected]>
1 parent 609c036 commit 6f5a767

File tree

5 files changed

+109
-120
lines changed

5 files changed

+109
-120
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ name = "cloudevents"
1919
[dependencies]
2020
serde = { version = "^1.0", features = ["derive"] }
2121
serde_json = "^1.0"
22-
serde-value = "^0.6"
2322
chrono = { version = "^0.4", features = ["serde"] }
2423
delegate-attr = "^0.2"
2524
base64 = "^0.12"
2625
url = { version = "^2.1", features = ["serde"] }
2726
snafu = "^0.6"
27+
bitflags = "^1.2"
2828

2929
[target."cfg(not(target_arch = \"wasm32\"))".dependencies]
3030
hostname = "^0.3"
@@ -38,6 +38,7 @@ uuid = { version = "^0.8", features = ["v4", "wasm-bindgen"] }
3838
rstest = "0.6"
3939
claim = "0.3.1"
4040
version-sync = "^0.9"
41+
serde_yaml = "0.8"
4142

4243
[workspace]
4344
members = [

src/event/format.rs

+45-91
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,45 @@ use super::{
33
EventFormatSerializerV03, EventFormatSerializerV10,
44
};
55
use crate::event::{AttributesReader, ExtensionValue};
6-
use serde::de::{Error, IntoDeserializer, Unexpected};
6+
use serde::de::{Error, IntoDeserializer};
77
use serde::{Deserialize, Deserializer, Serialize, Serializer};
8-
use serde_value::Value;
9-
use std::collections::{BTreeMap, HashMap};
8+
use serde_json::{Map, Value};
9+
use std::collections::HashMap;
1010

11-
macro_rules! parse_optional_field {
12-
($map:ident, $name:literal, $value_variant:ident, $error:ty) => {
11+
macro_rules! parse_field {
12+
($value:expr, $target_type:ty, $error:ty) => {
13+
<$target_type>::deserialize($value.into_deserializer()).map_err(<$error>::custom)
14+
};
15+
16+
($value:expr, $target_type:ty, $error:ty, $mapper:expr) => {
17+
<$target_type>::deserialize($value.into_deserializer())
18+
.map_err(<$error>::custom)
19+
.and_then(|v| $mapper(v).map_err(<$error>::custom))
20+
};
21+
}
22+
23+
macro_rules! extract_optional_field {
24+
($map:ident, $name:literal, $target_type:ty, $error:ty) => {
1325
$map.remove($name)
14-
.map(|val| match val {
15-
Value::$value_variant(v) => Ok(v),
16-
other => Err(<$error>::invalid_type(
17-
crate::event::format::value_to_unexpected(&other),
18-
&stringify!($value_variant),
19-
)),
20-
})
26+
.map(|v| parse_field!(v, $target_type, $error))
2127
.transpose()
2228
};
2329

24-
($map:ident, $name:literal, $value_variant:ident, $error:ty, $mapper:expr) => {
30+
($map:ident, $name:literal, $target_type:ty, $error:ty, $mapper:expr) => {
2531
$map.remove($name)
26-
.map(|val| match val {
27-
Value::$value_variant(v) => $mapper(&v).map_err(|e| {
28-
<$error>::invalid_value(
29-
crate::event::format::value_to_unexpected(&Value::$value_variant(v)),
30-
&e.to_string().as_str(),
31-
)
32-
}),
33-
other => Err(<$error>::invalid_type(
34-
crate::event::format::value_to_unexpected(&other),
35-
&stringify!($value_variant),
36-
)),
37-
})
32+
.map(|v| parse_field!(v, $target_type, $error, $mapper))
3833
.transpose()
3934
};
4035
}
4136

42-
macro_rules! parse_field {
43-
($map:ident, $name:literal, $value_variant:ident, $error:ty) => {
44-
parse_optional_field!($map, $name, $value_variant, $error)?
37+
macro_rules! extract_field {
38+
($map:ident, $name:literal, $target_type:ty, $error:ty) => {
39+
extract_optional_field!($map, $name, $target_type, $error)?
4540
.ok_or_else(|| <$error>::missing_field($name))
4641
};
4742

48-
($map:ident, $name:literal, $value_variant:ident, $error:ty, $mapper:expr) => {
49-
parse_optional_field!($map, $name, $value_variant, $error, $mapper)?
43+
($map:ident, $name:literal, $target_type:ty, $error:ty, $mapper:expr) => {
44+
extract_optional_field!($map, $name, $target_type, $error, $mapper)?
5045
.ok_or_else(|| <$error>::missing_field($name))
5146
};
5247
}
@@ -59,13 +54,7 @@ macro_rules! parse_data_json {
5954

6055
macro_rules! parse_data_string {
6156
($in:ident, $error:ty) => {
62-
match $in {
63-
Value::String(s) => Ok(s),
64-
other => Err(E::invalid_type(
65-
crate::event::format::value_to_unexpected(&other),
66-
&"a string",
67-
)),
68-
}
57+
parse_field!($in, String, $error)
6958
};
7059
}
7160

@@ -78,41 +67,39 @@ macro_rules! parse_json_data_base64 {
7867

7968
macro_rules! parse_data_base64 {
8069
($in:ident, $error:ty) => {
81-
match $in {
82-
Value::String(s) => base64::decode(&s).map_err(|e| {
70+
parse_field!($in, String, $error).and_then(|s| {
71+
base64::decode(&s).map_err(|e| {
8372
<$error>::invalid_value(serde::de::Unexpected::Str(&s), &e.to_string().as_str())
84-
}),
85-
other => Err(E::invalid_type(
86-
crate::event::format::value_to_unexpected(&other),
87-
&"a string",
88-
)),
89-
}
73+
})
74+
})
9075
};
9176
}
9277

9378
pub(crate) trait EventFormatDeserializer {
9479
fn deserialize_attributes<E: serde::de::Error>(
95-
map: &mut BTreeMap<String, Value>,
80+
map: &mut Map<String, Value>,
9681
) -> Result<Attributes, E>;
9782

9883
fn deserialize_data<E: serde::de::Error>(
9984
content_type: &str,
100-
map: &mut BTreeMap<String, Value>,
85+
map: &mut Map<String, Value>,
10186
) -> Result<Option<Data>, E>;
10287

103-
fn deserialize_event<E: serde::de::Error>(
104-
mut map: BTreeMap<String, Value>,
105-
) -> Result<Event, E> {
88+
fn deserialize_event<E: serde::de::Error>(mut map: Map<String, Value>) -> Result<Event, E> {
10689
let attributes = Self::deserialize_attributes(&mut map)?;
10790
let data = Self::deserialize_data(
10891
attributes.datacontenttype().unwrap_or("application/json"),
10992
&mut map,
11093
)?;
11194
let extensions = map
11295
.into_iter()
113-
.map(|(k, v)| Ok((k, ExtensionValue::deserialize(v.into_deserializer())?)))
114-
.collect::<Result<HashMap<String, ExtensionValue>, serde_value::DeserializerError>>()
115-
.map_err(E::custom)?;
96+
.map(|(k, v)| {
97+
Ok((
98+
k,
99+
ExtensionValue::deserialize(v.into_deserializer()).map_err(E::custom)?,
100+
))
101+
})
102+
.collect::<Result<HashMap<String, ExtensionValue>, E>>()?;
116103

117104
Ok(Event {
118105
attributes,
@@ -136,20 +123,12 @@ impl<'de> Deserialize<'de> for Event {
136123
where
137124
D: Deserializer<'de>,
138125
{
139-
let map = match Value::deserialize(deserializer)? {
140-
Value::Map(m) => Ok(m),
141-
v => Err(Error::invalid_type(value_to_unexpected(&v), &"a map")),
142-
}?;
126+
let root_value = Value::deserialize(deserializer)?;
127+
let mut map: Map<String, Value> =
128+
Map::deserialize(root_value.into_deserializer()).map_err(D::Error::custom)?;
143129

144-
let mut map: BTreeMap<String, Value> = map
145-
.into_iter()
146-
.map(|(k, v)| match k {
147-
Value::String(s) => Ok((s, v)),
148-
k => Err(Error::invalid_type(value_to_unexpected(&k), &"a string")),
149-
})
150-
.collect::<Result<BTreeMap<String, Value>, <D as Deserializer<'de>>::Error>>()?;
151-
152-
match parse_field!(map, "specversion", String, <D as Deserializer<'de>>::Error)?.as_str() {
130+
match extract_field!(map, "specversion", String, <D as Deserializer<'de>>::Error)?.as_str()
131+
{
153132
"0.3" => EventFormatDeserializerV03::deserialize_event(map),
154133
"1.0" => EventFormatDeserializerV10::deserialize_event(map),
155134
s => Err(D::Error::unknown_variant(
@@ -175,28 +154,3 @@ impl Serialize for Event {
175154
}
176155
}
177156
}
178-
179-
// This should be provided by the Value package itself
180-
pub(crate) fn value_to_unexpected(v: &Value) -> Unexpected {
181-
match v {
182-
Value::Bool(b) => serde::de::Unexpected::Bool(*b),
183-
Value::U8(n) => serde::de::Unexpected::Unsigned(*n as u64),
184-
Value::U16(n) => serde::de::Unexpected::Unsigned(*n as u64),
185-
Value::U32(n) => serde::de::Unexpected::Unsigned(*n as u64),
186-
Value::U64(n) => serde::de::Unexpected::Unsigned(*n),
187-
Value::I8(n) => serde::de::Unexpected::Signed(*n as i64),
188-
Value::I16(n) => serde::de::Unexpected::Signed(*n as i64),
189-
Value::I32(n) => serde::de::Unexpected::Signed(*n as i64),
190-
Value::I64(n) => serde::de::Unexpected::Signed(*n),
191-
Value::F32(n) => serde::de::Unexpected::Float(*n as f64),
192-
Value::F64(n) => serde::de::Unexpected::Float(*n),
193-
Value::Char(c) => serde::de::Unexpected::Char(*c),
194-
Value::String(s) => serde::de::Unexpected::Str(s),
195-
Value::Unit => serde::de::Unexpected::Unit,
196-
Value::Option(_) => serde::de::Unexpected::Option,
197-
Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
198-
Value::Seq(_) => serde::de::Unexpected::Seq,
199-
Value::Map(_) => serde::de::Unexpected::Map,
200-
Value::Bytes(b) => serde::de::Unexpected::Bytes(b),
201-
}
202-
}

src/event/v03/format.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@ use chrono::{DateTime, Utc};
55
use serde::de::IntoDeserializer;
66
use serde::ser::SerializeMap;
77
use serde::{Deserialize, Serializer};
8-
use serde_value::Value;
9-
use std::collections::{BTreeMap, HashMap};
8+
use serde_json::{Map, Value};
9+
use std::collections::HashMap;
1010
use url::Url;
1111

1212
pub(crate) struct EventFormatDeserializer {}
1313

1414
impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer {
1515
fn deserialize_attributes<E: serde::de::Error>(
16-
map: &mut BTreeMap<String, Value>,
16+
map: &mut Map<String, Value>,
1717
) -> Result<crate::event::Attributes, E> {
1818
Ok(crate::event::Attributes::V03(Attributes {
19-
id: parse_field!(map, "id", String, E)?,
20-
ty: parse_field!(map, "type", String, E)?,
21-
source: parse_field!(map, "source", String, E, Url::parse)?,
22-
datacontenttype: parse_optional_field!(map, "datacontenttype", String, E)?,
23-
schemaurl: parse_optional_field!(map, "schemaurl", String, E, Url::parse)?,
24-
subject: parse_optional_field!(map, "subject", String, E)?,
25-
time: parse_optional_field!(map, "time", String, E, |s| DateTime::parse_from_rfc3339(
26-
s
27-
)
28-
.map(DateTime::<Utc>::from))?,
19+
id: extract_field!(map, "id", String, E)?,
20+
ty: extract_field!(map, "type", String, E)?,
21+
source: extract_field!(map, "source", String, E, |s: String| Url::parse(&s))?,
22+
datacontenttype: extract_optional_field!(map, "datacontenttype", String, E)?,
23+
schemaurl: extract_optional_field!(map, "schemaurl", String, E, |s: String| {
24+
Url::parse(&s)
25+
})?,
26+
subject: extract_optional_field!(map, "subject", String, E)?,
27+
time: extract_optional_field!(map, "time", String, E, |s: String| {
28+
DateTime::parse_from_rfc3339(&s).map(DateTime::<Utc>::from)
29+
})?,
2930
}))
3031
}
3132

3233
fn deserialize_data<E: serde::de::Error>(
3334
content_type: &str,
34-
map: &mut BTreeMap<String, Value>,
35+
map: &mut Map<String, Value>,
3536
) -> Result<Option<Data>, E> {
3637
let data = map.remove("data");
3738
let is_base64 = map

src/event/v10/format.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@ use chrono::{DateTime, Utc};
55
use serde::de::IntoDeserializer;
66
use serde::ser::SerializeMap;
77
use serde::{Deserialize, Serializer};
8-
use serde_value::Value;
9-
use std::collections::{BTreeMap, HashMap};
8+
use serde_json::{Map, Value};
9+
use std::collections::HashMap;
1010
use url::Url;
1111

1212
pub(crate) struct EventFormatDeserializer {}
1313

1414
impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer {
1515
fn deserialize_attributes<E: serde::de::Error>(
16-
map: &mut BTreeMap<String, Value>,
16+
map: &mut Map<String, Value>,
1717
) -> Result<crate::event::Attributes, E> {
1818
Ok(crate::event::Attributes::V10(Attributes {
19-
id: parse_field!(map, "id", String, E)?,
20-
ty: parse_field!(map, "type", String, E)?,
21-
source: parse_field!(map, "source", String, E, Url::parse)?,
22-
datacontenttype: parse_optional_field!(map, "datacontenttype", String, E)?,
23-
dataschema: parse_optional_field!(map, "dataschema", String, E, Url::parse)?,
24-
subject: parse_optional_field!(map, "subject", String, E)?,
25-
time: parse_optional_field!(map, "time", String, E, |s| DateTime::parse_from_rfc3339(
26-
s
27-
)
28-
.map(DateTime::<Utc>::from))?,
19+
id: extract_field!(map, "id", String, E)?,
20+
ty: extract_field!(map, "type", String, E)?,
21+
source: extract_field!(map, "source", String, E, |s: String| Url::parse(&s))?,
22+
datacontenttype: extract_optional_field!(map, "datacontenttype", String, E)?,
23+
dataschema: extract_optional_field!(map, "dataschema", String, E, |s: String| {
24+
Url::parse(&s)
25+
})?,
26+
subject: extract_optional_field!(map, "subject", String, E)?,
27+
time: extract_optional_field!(map, "time", String, E, |s: String| {
28+
DateTime::parse_from_rfc3339(&s).map(DateTime::<Utc>::from)
29+
})?,
2930
}))
3031
}
3132

3233
fn deserialize_data<E: serde::de::Error>(
3334
content_type: &str,
34-
map: &mut BTreeMap<String, Value>,
35+
map: &mut Map<String, Value>,
3536
) -> Result<Option<Data>, E> {
3637
let data = map.remove("data");
3738
let data_base64 = map.remove("data_base64");

tests/serde_yaml.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use claim::*;
2+
use cloudevents::{Event, EventBuilder, EventBuilderV10};
3+
use serde_yaml;
4+
5+
mod test_data;
6+
7+
/// This test checks if the usage of serde_json::Value makes the Deserialize implementation incompatible with
8+
/// other Deserializers
9+
#[test]
10+
fn deserialize_should_succeed() {
11+
let input = r#"
12+
id: aaa
13+
type: bbb
14+
source: http://localhost
15+
datacontenttype: application/json
16+
data: true
17+
specversion: "1.0"
18+
"#;
19+
20+
let expected = EventBuilderV10::new()
21+
.id("aaa")
22+
.ty("bbb")
23+
.source("http://localhost")
24+
.data("application/json", serde_json::Value::Bool(true))
25+
.build()
26+
.unwrap();
27+
28+
let deserialize_result: Result<Event, serde_yaml::Error> = serde_yaml::from_str(input);
29+
assert_ok!(&deserialize_result);
30+
let deserialized = deserialize_result.unwrap();
31+
assert_eq!(deserialized, expected)
32+
}

0 commit comments

Comments
 (0)