`ParamsSpecs`: Make serialized form more concise
azriel91 opened this issue · 1 comments
azriel91 commented
Write custom serialization / deserialization code so that we don't get the extra layer of indentation.
Current:
app_download: !Value
value:
src: https://github.com/azriel91/web_app/releases/download/0.1.1/web_app.tar
dest: azriel91/web_app/0.1.1/web_app.tar
marker: null
s3_bucket: !FieldWise
field_wise_spec:
name: !Value
value: azriel-peace-envman-demo-1
marker: null
Desired:
app_download: !Value
src: https://github.com/azriel91/web_app/releases/download/0.1.1/web_app.tar
dest: azriel91/web_app/0.1.1/web_app.tar
s3_bucket: !FieldWise
name: !Value
value: azriel-peace-envman-demo-1
Tuple params fieldwise specs are tricky.
Current:
something: !FieldWise
field_wise_spec: !MappingFn
field_name: _0
fn_map: Some(Fn(&bool, &u16) -> Option<Vec<u8>>)
marker: null
Desired:
something: !FieldWise
_0: !MappingFn
fn_map: Some(Fn(&bool, &u16) -> Option<Vec<u8>>)
azriel91 commented
May be too magic to do this. Tried a few approaches:
-
#[serde(flatten)]
onParamsSpec::<T>::Value
andParamsSpec::FieldWise
:- does not work if
T
has unnamed fields. - message:
Error("can only flatten structs and maps (got a sequence)")
.
- does not work if
-
manually serializing
ParamsSpec
:Started on this, but it's weird when you get to
ParamsSpec::Value
, ideally you serialize self as an enum variant for the!Tag
, but then getT
to serialize its fields, which I don't think can be done:impl<T> Serialize for ParamsSpec<T> where T: Params + Clone + Debug + Serialize + Send + Sync + 'static, { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { match self { ParamsSpec::Stored => serializer.serialize_unit_variant("ParamsSpec", 0, "Stored"), ParamsSpec::Value { value } => { match T::type_kind() { TypeKind::Unit => serializer.serialize_unit_variant("ParamsSpec", 1, "Value"), TypeKind::Tuple => serializer.serialize_tuple_variant("ParamsSpec", 1, "Value", value.fields_unnamed()), TypeKind::Struct => serializer.serialize_struct_variant("ParamsSpec", 1, "Value", value.fields_named()), TypeKind::Enum => todo!(), } } ParamsSpec::InMemory => serializer.serialize_unit_variant("ParamsSpec", 2, "InMemory"), ParamsSpec::MappingFn(value) => serializer.serialize_newtype_variant("ParamsSpec", 3, "MappingFn", value), ParamsSpec::FieldWise { field_wise_spec } => todo!(), } } } /// The kind of type this is. /// /// Needed to determine how to serialize/deserialize a type at runtime. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum TypeKind { /// Unit struct with no fields. Unit, /// Tuple struct with unnamed fields. Tuple, /// Tuple struct with named fields. Named, /// Enum. Enum, }