1use super::Event;
2use snafu::Snafu;
3
4pub trait EventBuilder
22where
23 Self: Clone + Sized + From<Event> + Default,
24{
25 fn new() -> Self;
27
28 fn build(self) -> Result<Event, Error>;
30}
31
32#[derive(Debug, Snafu, Clone)]
34pub enum Error {
35 #[snafu(display("Missing required attribute {}", attribute_name))]
36 MissingRequiredAttribute { attribute_name: &'static str },
37 #[snafu(display(
38 "Error while setting attribute '{}' with timestamp type: {}",
39 attribute_name,
40 source
41 ))]
42 ParseTimeError {
43 attribute_name: &'static str,
44 source: chrono::ParseError,
45 },
46 #[snafu(display(
47 "Error while setting attribute '{}' with uri type: {}",
48 attribute_name,
49 source
50 ))]
51 ParseUrlError {
52 attribute_name: &'static str,
53 source: url::ParseError,
54 },
55 #[snafu(display(
56 "Invalid value setting attribute '{}' with uriref type",
57 attribute_name,
58 ))]
59 InvalidUriRefError { attribute_name: &'static str },
60}
61
62#[cfg(test)]
63mod tests {
64 use crate::test::fixtures;
65 use crate::Event;
66 use crate::EventBuilder;
67 use crate::EventBuilderV03;
68 use crate::EventBuilderV10;
69 use claims::*;
70 use rstest::rstest;
71 use serde_json::{json, Value};
72 use serde_yaml;
73
74 #[test]
77 fn v10_to_v03() {
78 let in_event = fixtures::v10::full_json_data();
79 let out_event = EventBuilderV03::from(in_event).build().unwrap();
80 assert_eq!(fixtures::v03::full_json_data(), out_event)
81 }
82
83 #[test]
84 fn v03_to_v10() {
85 let in_event = fixtures::v03::full_json_data();
86 let out_event = EventBuilderV10::from(in_event).build().unwrap();
87 assert_eq!(fixtures::v10::full_json_data(), out_event)
88 }
89
90 #[test]
94 fn deserialize_yaml_should_succeed() {
95 let input = r#"
96 id: aaa
97 type: bbb
98 source: http://localhost
99 datacontenttype: application/json
100 data: true
101 specversion: "1.0"
102 "#;
103
104 let expected = EventBuilderV10::new()
105 .id("aaa")
106 .ty("bbb")
107 .source("http://localhost")
108 .data("application/json", serde_json::Value::Bool(true))
109 .build()
110 .unwrap();
111
112 let deserialize_result: Result<Event, serde_yaml::Error> = serde_yaml::from_str(input);
113 assert_ok!(&deserialize_result);
114 let deserialized = deserialize_result.unwrap();
115 assert_eq!(deserialized, expected)
116 }
117
118 #[rstest(
121 in_event,
122 out_json,
123 case::minimal_v03(fixtures::v03::minimal(), fixtures::v03::minimal_json()),
124 case::full_v03_no_data(fixtures::v03::full_no_data(), fixtures::v03::full_no_data_json()),
125 case::full_v03_with_json_data(
126 fixtures::v03::full_json_data(),
127 fixtures::v03::full_json_data_json()
128 ),
129 case::full_v03_with_xml_string_data(
130 fixtures::v03::full_xml_string_data(),
131 fixtures::v03::full_xml_string_data_json()
132 ),
133 case::full_v03_with_xml_base64_data(
134 fixtures::v03::full_xml_binary_data(),
135 fixtures::v03::full_xml_base64_data_json()
136 ),
137 case::minimal_v10(fixtures::v10::minimal(), fixtures::v10::minimal_json()),
138 case::full_v10_no_data(fixtures::v10::full_no_data(), fixtures::v10::full_no_data_json()),
139 case::full_v10_with_json_data(
140 fixtures::v10::full_json_data(),
141 fixtures::v10::full_json_data_json()
142 ),
143 case::full_v10_with_xml_string_data(
144 fixtures::v10::full_xml_string_data(),
145 fixtures::v10::full_xml_string_data_json()
146 ),
147 case::full_v10_with_xml_base64_data(
148 fixtures::v10::full_xml_binary_data(),
149 fixtures::v10::full_xml_base64_data_json()
150 )
151 )]
152 fn serialize_should_succeed(in_event: Event, out_json: Value) {
153 let serialize_result = serde_json::to_value(in_event.clone());
155 assert_ok!(&serialize_result);
156 let actual_json = serialize_result.unwrap();
157 assert_eq!(&actual_json, &out_json);
158
159 let actual_json_serialized = actual_json.to_string();
161 assert_eq!(actual_json_serialized, out_json.to_string());
162
163 let deserialize_result: Result<Event, serde_json::Error> =
165 serde_json::from_str(&actual_json_serialized);
166 assert_ok!(&deserialize_result);
167 let deserialize_json = deserialize_result.unwrap();
168 assert_eq!(deserialize_json, in_event)
169 }
170
171 #[rstest(
173 in_json,
174 out_event,
175 case::minimal_v03(fixtures::v03::minimal_json(), fixtures::v03::minimal()),
176 case::full_v03_no_data(fixtures::v03::full_no_data_json(), fixtures::v03::full_no_data()),
177 case::full_v03_with_json_data(
178 fixtures::v03::full_json_data_json(),
179 fixtures::v03::full_json_data()
180 ),
181 case::full_v03_with_json_base64_data(
182 fixtures::v03::full_json_base64_data_json(),
183 fixtures::v03::full_json_data()
184 ),
185 case::full_v03_with_xml_string_data(
186 fixtures::v03::full_xml_string_data_json(),
187 fixtures::v03::full_xml_string_data()
188 ),
189 case::full_v03_with_xml_base64_data(
190 fixtures::v03::full_xml_base64_data_json(),
191 fixtures::v03::full_xml_binary_data()
192 ),
193 case::minimal_v10(fixtures::v10::minimal_json(), fixtures::v10::minimal()),
194 case::full_v10_no_data(fixtures::v10::full_no_data_json(), fixtures::v10::full_no_data()),
195 case::full_v10_with_json_data(
196 fixtures::v10::full_json_data_json(),
197 fixtures::v10::full_json_data()
198 ),
199 case::full_v10_with_json_base64_data(
200 fixtures::v10::full_json_base64_data_json(),
201 fixtures::v10::full_json_data()
202 ),
203 case::full_v10_with_non_json_base64_data(
204 fixtures::v10::full_non_json_base64_data(),
205 fixtures::v10::full_non_json_data()
206 ),
207 case::full_v10_with_xml_string_data(
208 fixtures::v10::full_xml_string_data_json(),
209 fixtures::v10::full_xml_string_data()
210 ),
211 case::full_v10_with_xml_base64_data(
212 fixtures::v10::full_xml_base64_data_json(),
213 fixtures::v10::full_xml_binary_data()
214 )
215 )]
216 fn deserialize_json_should_succeed(in_json: Value, out_event: Event) {
217 let deserialize_result: Result<Event, serde_json::Error> = serde_json::from_value(in_json);
218 assert_ok!(&deserialize_result);
219 let deserialize_json = deserialize_result.unwrap();
220 assert_eq!(deserialize_json, out_event)
221 }
222
223 #[test]
224 fn deserialize_with_null_attribute() {
225 let in_json = json!({
226 "specversion" : "1.0",
227 "type" : "com.example.someevent",
228 "source" : "/mycontext",
229 "id" : "A234-1234-1234",
230 "time" : null,
231 "comexampleextension1" : "value",
232 "comexampleothervalue" : 5,
233 "datacontenttype" : "text/xml",
234 "data" : "<much wow=\"xml\"/>"
235 });
236
237 let out_event = EventBuilderV10::new()
238 .ty("com.example.someevent")
239 .source("/mycontext")
240 .id("A234-1234-1234")
241 .data("text/xml", "<much wow=\"xml\"/>")
242 .extension("comexampleextension1", "value")
243 .extension("comexampleothervalue", 5)
244 .build()
245 .unwrap();
246
247 let deserialize_result: Result<Event, serde_json::Error> = serde_json::from_value(in_json);
248 assert_ok!(&deserialize_result);
249 let deserialize_json = deserialize_result.unwrap();
250 assert_eq!(deserialize_json, out_event)
251 }
252
253 #[test]
254 fn deserialize_with_null_ext() {
255 let in_json = json!({
256 "specversion" : "1.0",
257 "type" : "com.example.someevent",
258 "source" : "/mycontext",
259 "id" : "A234-1234-1234",
260 "time" : "2018-04-05T17:31:00Z",
261 "comexampleextension1" : "value",
262 "comexampleothervalue" : 5,
263 "unsetextension": null,
264 "datacontenttype" : "text/xml",
265 "data" : "<much wow=\"xml\"/>"
266 });
267
268 let out_event = EventBuilderV10::new()
269 .ty("com.example.someevent")
270 .source("/mycontext")
271 .id("A234-1234-1234")
272 .time("2018-04-05T17:31:00Z")
273 .data("text/xml", "<much wow=\"xml\"/>")
274 .extension("comexampleextension1", "value")
275 .extension("comexampleothervalue", 5)
276 .build()
277 .unwrap();
278
279 let deserialize_result: Result<Event, serde_json::Error> = serde_json::from_value(in_json);
280 assert_ok!(&deserialize_result);
281 let deserialize_json = deserialize_result.unwrap();
282 assert_eq!(deserialize_json, out_event)
283 }
284}