De-macro-fy data parsing

The code is more legible without them, I think. I'm not sure their
complexity is justified.

Signed-off-by: Jim Crossley <jim@crossleys.org>
This commit is contained in:
Jim Crossley 2021-11-11 15:33:26 -05:00
parent 05807fdf28
commit 66b9bfde1b
3 changed files with 28 additions and 35 deletions

View File

@ -48,33 +48,23 @@ macro_rules! extract_field {
}; };
} }
macro_rules! parse_data_json { pub fn parse_data_json<E: serde::de::Error>(v: Value) -> Result<Value, E> {
($in:ident, $error:ty) => { Value::deserialize(v.into_deserializer()).map_err(E::custom)
serde_json::Value::deserialize($in.into_deserializer()).map_err(<$error>::custom)
};
} }
macro_rules! parse_data_string { pub fn parse_data_string<E: serde::de::Error>(v: Value) -> Result<String, E> {
($in:ident, $error:ty) => { parse_field!(v, String, E)
parse_field!($in, String, $error)
};
} }
macro_rules! parse_json_data_base64 { pub fn parse_data_base64<E: serde::de::Error>(v: Value) -> Result<Vec<u8>, E> {
($in:ident, $error:ty) => {{ parse_field!(v, String, E).and_then(|s| {
let data = parse_data_base64!($in, $error)?; base64::decode(&s).map_err(|e| E::custom(format_args!("decode error `{}`", e)))
serde_json::from_slice(&data).map_err(<$error>::custom) })
}};
} }
macro_rules! parse_data_base64 { pub fn parse_data_base64_json<E: serde::de::Error>(v: Value) -> Result<Value, E> {
($in:ident, $error:ty) => { let data = parse_data_base64(v)?;
parse_field!($in, String, $error).and_then(|s| { serde_json::from_slice(&data).map_err(E::custom)
base64::decode(&s).map_err(|e| {
<$error>::invalid_value(serde::de::Unexpected::Str(&s), &e.to_string().as_str())
})
})
};
} }
pub(crate) trait EventFormatDeserializer { pub(crate) trait EventFormatDeserializer {

View File

@ -1,5 +1,8 @@
use super::Attributes; use super::Attributes;
use crate::event::data::is_json_content_type; use crate::event::data::is_json_content_type;
use crate::event::format::{
parse_data_base64, parse_data_base64_json, parse_data_json, parse_data_string,
};
use crate::event::{Data, ExtensionValue}; use crate::event::{Data, ExtensionValue};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
@ -45,10 +48,10 @@ impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer {
let is_json = is_json_content_type(content_type); let is_json = is_json_content_type(content_type);
Ok(match (data, is_base64, is_json) { Ok(match (data, is_base64, is_json) {
(Some(d), false, true) => Some(Data::Json(parse_data_json!(d, E)?)), (Some(d), false, true) => Some(Data::Json(parse_data_json(d)?)),
(Some(d), false, false) => Some(Data::String(parse_data_string!(d, E)?)), (Some(d), false, false) => Some(Data::String(parse_data_string(d)?)),
(Some(d), true, true) => Some(Data::Json(parse_json_data_base64!(d, E)?)), (Some(d), true, true) => Some(Data::Json(parse_data_base64_json(d)?)),
(Some(d), true, false) => Some(Data::Binary(parse_data_base64!(d, E)?)), (Some(d), true, false) => Some(Data::Binary(parse_data_base64(d)?)),
(None, _, _) => None, (None, _, _) => None,
}) })
} }

View File

@ -1,5 +1,8 @@
use super::Attributes; use super::Attributes;
use crate::event::data::is_json_content_type; use crate::event::data::is_json_content_type;
use crate::event::format::{
parse_data_base64, parse_data_base64_json, parse_data_json, parse_data_string,
};
use crate::event::{Data, ExtensionValue}; use crate::event::{Data, ExtensionValue};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
@ -40,16 +43,13 @@ impl crate::event::format::EventFormatDeserializer for EventFormatDeserializer {
let is_json = is_json_content_type(content_type); let is_json = is_json_content_type(content_type);
Ok(match (data, data_base64, is_json) { Ok(match (data, data_base64, is_json) {
(Some(d), None, true) => Some(Data::Json(parse_data_json!(d, E)?)), (Some(d), None, true) => Some(Data::Json(parse_data_json(d)?)),
(Some(d), None, false) => Some(Data::String(parse_data_string!(d, E)?)), (Some(d), None, false) => Some(Data::String(parse_data_string(d)?)),
(None, Some(d), true) => { (None, Some(d), true) => match parse_data_base64_json::<E>(d.to_owned()) {
let dc = d.to_owned(); Ok(x) => Some(Data::Json(x)),
match parse_json_data_base64!(dc, E) { Err(_) => Some(Data::Binary(parse_data_base64(d)?)),
Ok(x) => Some(Data::Json(x)), },
Err(_) => Some(Data::Binary(parse_data_base64!(d, E)?)), (None, Some(d), false) => Some(Data::Binary(parse_data_base64(d)?)),
}
}
(None, Some(d), false) => Some(Data::Binary(parse_data_base64!(d, E)?)),
(Some(_), Some(_), _) => { (Some(_), Some(_), _) => {
return Err(E::custom("Cannot have both data and data_base64 field")) return Err(E::custom("Cannot have both data and data_base64 field"))
} }