cloudevents/event/
format.rs

1use super::{
2    Attributes, Data, Event, EventFormatDeserializerV03, EventFormatDeserializerV10,
3    EventFormatSerializerV03, EventFormatSerializerV10,
4};
5use crate::event::{AttributesReader, ExtensionValue};
6use base64::prelude::*;
7use serde::de::{Error, IntoDeserializer};
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use serde_json::{Map, Value};
10use std::collections::HashMap;
11
12macro_rules! parse_field {
13    ($value:expr, $target_type:ty, $error:ty) => {
14        <$target_type>::deserialize($value.into_deserializer()).map_err(<$error>::custom)
15    };
16
17    ($value:expr, $target_type:ty, $error:ty, $mapper:expr) => {
18        <$target_type>::deserialize($value.into_deserializer())
19            .map_err(<$error>::custom)
20            .and_then(|v| $mapper(v).map_err(<$error>::custom))
21    };
22}
23
24macro_rules! extract_optional_field {
25    ($map:ident, $name:literal, $target_type:ty, $error:ty) => {
26        $map.remove($name)
27            .filter(|v| !v.is_null())
28            .map(|v| parse_field!(v, $target_type, $error))
29            .transpose()
30    };
31
32    ($map:ident, $name:literal, $target_type:ty, $error:ty, $mapper:expr) => {
33        $map.remove($name)
34            .filter(|v| !v.is_null())
35            .map(|v| parse_field!(v, $target_type, $error, $mapper))
36            .transpose()
37    };
38}
39
40macro_rules! extract_field {
41    ($map:ident, $name:literal, $target_type:ty, $error:ty) => {
42        extract_optional_field!($map, $name, $target_type, $error)?
43            .ok_or_else(|| <$error>::missing_field($name))
44    };
45
46    ($map:ident, $name:literal, $target_type:ty, $error:ty, $mapper:expr) => {
47        extract_optional_field!($map, $name, $target_type, $error, $mapper)?
48            .ok_or_else(|| <$error>::missing_field($name))
49    };
50}
51
52pub fn parse_data_json<E: serde::de::Error>(v: Value) -> Result<Value, E> {
53    Value::deserialize(v.into_deserializer()).map_err(E::custom)
54}
55
56pub fn parse_data_string<E: serde::de::Error>(v: Value) -> Result<String, E> {
57    parse_field!(v, String, E)
58}
59
60pub fn parse_data_base64<E: serde::de::Error>(v: Value) -> Result<Vec<u8>, E> {
61    parse_field!(v, String, E).and_then(|s| {
62        BASE64_STANDARD
63            .decode(s)
64            .map_err(|e| E::custom(format_args!("decode error `{}`", e)))
65    })
66}
67
68pub fn parse_data_base64_json<E: serde::de::Error>(v: Value) -> Result<Value, E> {
69    let data = parse_data_base64(v)?;
70    serde_json::from_slice(&data).map_err(E::custom)
71}
72
73pub(crate) trait EventFormatDeserializer {
74    fn deserialize_attributes<E: serde::de::Error>(
75        map: &mut Map<String, Value>,
76    ) -> Result<Attributes, E>;
77
78    fn deserialize_data<E: serde::de::Error>(
79        content_type: &str,
80        map: &mut Map<String, Value>,
81    ) -> Result<Option<Data>, E>;
82
83    fn deserialize_event<E: serde::de::Error>(mut map: Map<String, Value>) -> Result<Event, E> {
84        let attributes = Self::deserialize_attributes(&mut map)?;
85        let data = Self::deserialize_data(
86            attributes.datacontenttype().unwrap_or("application/json"),
87            &mut map,
88        )?;
89        let extensions = map
90            .into_iter()
91            .filter(|v| !v.1.is_null())
92            .map(|(k, v)| {
93                Ok((
94                    k,
95                    ExtensionValue::deserialize(v.into_deserializer()).map_err(E::custom)?,
96                ))
97            })
98            .collect::<Result<HashMap<String, ExtensionValue>, E>>()?;
99
100        Ok(Event {
101            attributes,
102            data,
103            extensions,
104        })
105    }
106}
107
108pub(crate) trait EventFormatSerializer<S: Serializer, A: Sized> {
109    fn serialize(
110        attributes: &A,
111        data: &Option<Data>,
112        extensions: &HashMap<String, ExtensionValue>,
113        serializer: S,
114    ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>;
115}
116
117impl<'de> Deserialize<'de> for Event {
118    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
119    where
120        D: Deserializer<'de>,
121    {
122        let root_value = Value::deserialize(deserializer)?;
123        let mut map: Map<String, Value> =
124            Map::deserialize(root_value.into_deserializer()).map_err(D::Error::custom)?;
125
126        match extract_field!(map, "specversion", String, <D as Deserializer<'de>>::Error)?.as_str()
127        {
128            "0.3" => EventFormatDeserializerV03::deserialize_event(map),
129            "1.0" => EventFormatDeserializerV10::deserialize_event(map),
130            s => Err(D::Error::unknown_variant(
131                s,
132                &super::spec_version::SPEC_VERSIONS,
133            )),
134        }
135    }
136}
137
138impl Serialize for Event {
139    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
140    where
141        S: Serializer,
142    {
143        match &self.attributes {
144            Attributes::V03(a) => {
145                EventFormatSerializerV03::serialize(a, &self.data, &self.extensions, serializer)
146            }
147            Attributes::V10(a) => {
148                EventFormatSerializerV10::serialize(a, &self.data, &self.extensions, serializer)
149            }
150        }
151    }
152}