From 1356ca0bc1488ca6a1c3f541358af459e3a4fda8 Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Thu, 14 Aug 2025 19:03:36 +0200 Subject: fix(config): rule serialisation --- lib/warden-core/build.rs | 12 ++++ lib/warden-core/src/configuration.rs | 2 + lib/warden-core/src/configuration/conv.rs | 109 ++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 lib/warden-core/src/configuration/conv.rs (limited to 'lib') diff --git a/lib/warden-core/build.rs b/lib/warden-core/build.rs index c0496d9..abc6e37 100644 --- a/lib/warden-core/build.rs +++ b/lib/warden-core/build.rs @@ -121,6 +121,18 @@ fn add_serde(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder { "#[serde(try_from = \"crate::google::parser::dt::DateItem\")] #[serde(into = \"String\")]", ).type_attribute(".google.type.Date", "#[serde(try_from = \"crate::google::parser::dt::DateItem\")] #[serde(into = \"String\")]"); + #[cfg(feature = "configuration")] + let config = config + .field_attribute(".configuration.rule.Config.cases", "#[serde(default)]") + .field_attribute( + ".configuration.rule.Config.time_frames", + "#[serde(default)]", + ) + .type_attribute( + ".google.protobuf.Value", + "#[serde(try_from = \"serde_json::Value\")] #[serde(into = \"crate::configuration::conv::GenericParameter\")]", + ); + config } diff --git a/lib/warden-core/src/configuration.rs b/lib/warden-core/src/configuration.rs index 798c079..c6b24ce 100644 --- a/lib/warden-core/src/configuration.rs +++ b/lib/warden-core/src/configuration.rs @@ -1,3 +1,5 @@ +pub(crate) mod conv; + tonic::include_proto!("configuration"); pub mod routing { diff --git a/lib/warden-core/src/configuration/conv.rs b/lib/warden-core/src/configuration/conv.rs new file mode 100644 index 0000000..c5c7768 --- /dev/null +++ b/lib/warden-core/src/configuration/conv.rs @@ -0,0 +1,109 @@ +use crate::google::protobuf::{ListValue, NullValue, Struct, Value, value}; + +#[derive(Debug)] +/// Generic JSON value +pub struct GenericParameter(pub(crate) serde_json::Value); + +impl From for GenericParameter { + fn from(value: Value) -> Self { + Self(value.into()) + } +} + +impl From for GenericParameter { + fn from(value: value::Kind) -> Self { + Self(value.into()) + } +} + +impl TryFrom for value::Kind { + type Error = String; + + fn try_from(value: serde_json::Value) -> Result { + match value { + serde_json::Value::Null => Ok(value::Kind::NullValue(NullValue::NullValue as i32)), + serde_json::Value::Bool(b) => Ok(value::Kind::BoolValue(b)), + serde_json::Value::Number(n) => n + .as_f64() + .map(value::Kind::NumberValue) + .ok_or_else(|| "Invalid number".to_string()), + serde_json::Value::String(s) => Ok(value::Kind::StringValue(s)), + serde_json::Value::Array(arr) => { + let values = arr + .into_iter() + .map(Value::try_from) + .collect::, _>>()?; + Ok(value::Kind::ListValue(ListValue { values })) + } + serde_json::Value::Object(map) => { + let mut fields = std::collections::HashMap::new(); + for (k, v) in map { + let v = Value::try_from(v)?; + fields.insert(k, v); + } + Ok(value::Kind::StructValue(Struct { fields })) + } + } + } +} + +impl TryFrom for Value { + type Error = String; + + fn try_from(value: serde_json::Value) -> Result { + let kind = Some(value::Kind::try_from(value)?); + Ok(Value { kind }) + } +} + +impl From for serde_json::Value { + fn from(kind: value::Kind) -> Self { + match kind { + value::Kind::NullValue(_) => serde_json::Value::Null, + value::Kind::BoolValue(b) => serde_json::Value::Bool(b), + value::Kind::NumberValue(n) => serde_json::Value::Number( + serde_json::Number::from_f64(n).unwrap_or_else(|| serde_json::Number::from(0)), + ), + value::Kind::StringValue(s) => serde_json::Value::String(s), + value::Kind::StructValue(s) => serde_json::Value::from(s), + value::Kind::ListValue(l) => serde_json::Value::from(l), + } + } +} + +impl From for serde_json::Value { + fn from(value: Value) -> Self { + match value.kind { + Some(kind) => kind.into(), + None => serde_json::Value::Null, + } + } +} + +impl From for serde_json::Value { + fn from(s: Struct) -> Self { + let map = s + .fields + .into_iter() + .map(|(k, v)| (k, serde_json::Value::from(v))) + .collect(); + serde_json::Value::Object(map) + } +} + +impl From for serde_json::Value { + fn from(l: ListValue) -> Self { + let list = l.values.into_iter().map(serde_json::Value::from).collect(); + serde_json::Value::Array(list) + } +} + +impl serde::Serialize for GenericParameter { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let json = serde_json::Value::from(self.0.clone()); + json.serialize(serializer) + } +} -- cgit v1.2.3