Skip to content

Commit

Permalink
Better union serialization #71
Browse files Browse the repository at this point in the history
  • Loading branch information
lerouxrgd committed Sep 3, 2024
1 parent 7e0f600 commit b593eff
Show file tree
Hide file tree
Showing 12 changed files with 742 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rsgen-avro"
version = "0.14.2"
version = "0.15.0"
authors = ["Romain Leroux <romain@leroux.dev>"]
edition = "2021"
description = "Command line and library for generating Rust types from Avro schemas"
Expand Down
75 changes: 73 additions & 2 deletions src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ pub enum {{ name }} {
pub const UNION_TERA: &str = "union.tera";
pub const UNION_TEMPLATE: &str = r#"
/// Auto-generated type for unnamed Avro union variants.
#[derive(Debug, PartialEq{%- if is_eq_derivable %}, Eq{%- endif %}, Clone{%- if not use_avro_rs_unions %}, serde::Deserialize {%- endif %}, serde::Serialize)]
#[derive(Debug, PartialEq{%- if is_eq_derivable %}, Eq{%- endif %}, Clone, serde::Deserialize, serde::Serialize)]
#[serde(remote = "Self")]
pub enum {{ name }} {
{%- for s in symbols %}
{{ s }},
Expand Down Expand Up @@ -160,8 +161,69 @@ impl TryFrom<{{ name }}> for {{ v.rust_type }} {
{%- endif %}
{%- endfor %}
{%- if use_avro_rs_unions %}
impl serde::Serialize for {{ name }} {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
struct NewtypeVariantSerializer<S>(S);
impl<S> serde::Serializer for NewtypeVariantSerializer<S>
where
S: serde::Serializer,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeSeq = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTuple = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleVariant = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeMap = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStructVariant = serde::ser::Impossible<S::Ok, S::Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_none(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_some<T: ?Sized + serde::Serialize>(self, _value: &T) -> Result<Self::Ok, Self::Error>{ unimplemented!() }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_variant(self ,_name: &'static str, _variant_index: u32, _variant: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(self, _name: &'static str, _value: &T,) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_seq(self,_len: Option<usize>,) -> Result<Self::SerializeSeq, Self::Error> { unimplemented!() }
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { unimplemented!() }
fn serialize_tuple_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> { unimplemented!() }
fn serialize_tuple_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeTupleVariant, Self::Error> { unimplemented!() }
fn serialize_map(self,_len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { unimplemented!() }
fn serialize_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeStruct, Self::Error> { unimplemented!() }
fn serialize_struct_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeStructVariant, Self::Error> { unimplemented!() }
fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self.0)
}
}
Self::serialize(self, NewtypeVariantSerializer(serializer))
}
}
{# #}
{%- if use_avro_rs_unions %}
impl<'de> serde::Deserialize<'de> for {{ name }} {
fn deserialize<D>(deserializer: D) -> Result<{{ name }}, D::Error>
where
Expand Down Expand Up @@ -192,6 +254,15 @@ impl<'de> serde::Deserialize<'de> for {{ name }} {
deserializer.deserialize_any({{ name }}Visitor)
}
}
{%- else %}
impl<'de> serde::Deserialize<'de> for {{ name }} {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Self::deserialize(deserializer)
}
}
{%- endif %}
"#;

Expand Down
72 changes: 72 additions & 0 deletions tests/schemas/interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum Kind {

/// Auto-generated type for unnamed Avro union variants.
#[derive(Debug, PartialEq, Clone, serde::Deserialize, serde::Serialize)]
#[serde(remote = "Self")]
pub enum UnionBooleanDoubleArrayBytes {
Boolean(bool),
Double(f64),
Expand Down Expand Up @@ -63,6 +64,77 @@ impl TryFrom<UnionBooleanDoubleArrayBytes> for f64 {
}
}

impl serde::Serialize for UnionBooleanDoubleArrayBytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
struct NewtypeVariantSerializer<S>(S);

impl<S> serde::Serializer for NewtypeVariantSerializer<S>
where
S: serde::Serializer,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeSeq = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTuple = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleVariant = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeMap = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStructVariant = serde::ser::Impossible<S::Ok, S::Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_none(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_some<T: ?Sized + serde::Serialize>(self, _value: &T) -> Result<Self::Ok, Self::Error>{ unimplemented!() }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_variant(self ,_name: &'static str, _variant_index: u32, _variant: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(self, _name: &'static str, _value: &T,) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_seq(self,_len: Option<usize>,) -> Result<Self::SerializeSeq, Self::Error> { unimplemented!() }
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { unimplemented!() }
fn serialize_tuple_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> { unimplemented!() }
fn serialize_tuple_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeTupleVariant, Self::Error> { unimplemented!() }
fn serialize_map(self,_len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { unimplemented!() }
fn serialize_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeStruct, Self::Error> { unimplemented!() }
fn serialize_struct_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeStructVariant, Self::Error> { unimplemented!() }
fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self.0)
}
}

Self::serialize(self, NewtypeVariantSerializer(serializer))
}
}

impl<'de> serde::Deserialize<'de> for UnionBooleanDoubleArrayBytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Self::deserialize(deserializer)
}
}

#[derive(Debug, PartialEq, Clone, serde::Deserialize, serde::Serialize)]
pub struct Interop {
#[serde(rename = "intField")]
Expand Down
72 changes: 72 additions & 0 deletions tests/schemas/mono_valued_union.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

/// Auto-generated type for unnamed Avro union variants.
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
#[serde(remote = "Self")]
pub enum UnionLong {
Long(i64),
}
Expand All @@ -18,6 +19,77 @@ impl From<UnionLong> for i64 {
}
}

impl serde::Serialize for UnionLong {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
struct NewtypeVariantSerializer<S>(S);

impl<S> serde::Serializer for NewtypeVariantSerializer<S>
where
S: serde::Serializer,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeSeq = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTuple = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeTupleVariant = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeMap = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStruct = serde::ser::Impossible<S::Ok, S::Error>;
type SerializeStructVariant = serde::ser::Impossible<S::Ok, S::Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_none(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_some<T: ?Sized + serde::Serialize>(self, _value: &T) -> Result<Self::Ok, Self::Error>{ unimplemented!() }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_unit_variant(self ,_name: &'static str, _variant_index: u32, _variant: &'static str) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_newtype_struct<T: ?Sized + serde::Serialize>(self, _name: &'static str, _value: &T,) -> Result<Self::Ok, Self::Error> { unimplemented!() }
fn serialize_seq(self,_len: Option<usize>,) -> Result<Self::SerializeSeq, Self::Error> { unimplemented!() }
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { unimplemented!() }
fn serialize_tuple_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> { unimplemented!() }
fn serialize_tuple_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeTupleVariant, Self::Error> { unimplemented!() }
fn serialize_map(self,_len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { unimplemented!() }
fn serialize_struct(self,_name: &'static str,_len: usize) -> Result<Self::SerializeStruct, Self::Error> { unimplemented!() }
fn serialize_struct_variant(self,_name: &'static str,_variant_index: u32,_variant: &'static str,_len: usize) -> Result<Self::SerializeStructVariant, Self::Error> { unimplemented!() }
fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error> {
value.serialize(self.0)
}
}

Self::serialize(self, NewtypeVariantSerializer(serializer))
}
}

impl<'de> serde::Deserialize<'de> for UnionLong {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Self::deserialize(deserializer)
}
}

#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct Mono {
#[serde(rename = "myField")]
Expand Down
Loading

0 comments on commit b593eff

Please sign in to comment.