#![allow(dead_code, unused_imports, clippy::all)]
use delta_pack::IndexMap;
use delta_pack::{Decoder, Encoder};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum HairColor {
BLACK,
BROWN,
BLOND,
RED,
WHITE,
OTHER,
}
impl HairColor {
pub const NUM_BITS: u8 = 3;
pub fn from_u32(val: u32) -> Self {
match val {
0 => HairColor::BLACK,
1 => HairColor::BROWN,
2 => HairColor::BLOND,
3 => HairColor::RED,
4 => HairColor::WHITE,
5 => HairColor::OTHER,
_ => panic!("Invalid HairColor value: {}", val),
}
}
pub fn to_u32(self) -> u32 {
match self {
HairColor::BLACK => 0,
HairColor::BROWN => 1,
HairColor::BLOND => 2,
HairColor::RED => 3,
HairColor::WHITE => 4,
HairColor::OTHER => 5,
}
}
}
impl Default for HairColor {
fn default() -> Self {
HairColor::BLACK
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Address {
pub street: String,
pub zip: String,
pub state: String,
}
impl Default for Address {
fn default() -> Self {
Self {
street: String::new(),
zip: String::new(),
state: String::new(),
}
}
}
impl Address {
pub fn equals(&self, other: &Self) -> bool {
self.street == other.street && self.zip == other.zip && self.state == other.state
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.street);
encoder.push_string(&self.zip);
encoder.push_string(&self.state);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.street,
&b.street,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.zip,
&b.zip,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.state,
&b.state,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
street: decoder.next_string(),
zip: decoder.next_string(),
state: decoder.next_string(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
street: decoder.next_field_diff(&obj.street, |dec, a| dec.next_string_diff(a)),
zip: decoder.next_field_diff(&obj.zip, |dec, a| dec.next_string_diff(a)),
state: decoder.next_field_diff(&obj.state, |dec, a| dec.next_string_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EmailContact {
pub email: String,
}
impl Default for EmailContact {
fn default() -> Self {
Self {
email: String::new(),
}
}
}
impl EmailContact {
pub fn equals(&self, other: &Self) -> bool {
self.email == other.email
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.email);
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.email,
&b.email,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
email: decoder.next_string(),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
email: decoder.next_field_diff(&obj.email, |dec, a| dec.next_string_diff(a)),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PhoneContact {
pub phone: String,
pub extension: Option<u64>,
}
impl Default for PhoneContact {
fn default() -> Self {
Self {
phone: String::new(),
extension: None,
}
}
}
impl PhoneContact {
pub fn equals(&self, other: &Self) -> bool {
self.phone == other.phone && self.extension == other.extension
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.phone);
encoder.push_optional(&self.extension, |enc, &item| enc.push_uint(item));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.phone,
&b.phone,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.extension,
&b.extension,
|x, y| x == y,
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, &item| enc.push_uint(item),
|enc, &a, &b| enc.push_uint_diff(a, b),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
phone: decoder.next_string(),
extension: decoder.next_optional(|dec| dec.next_uint()),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
phone: decoder.next_field_diff(&obj.phone, |dec, a| dec.next_string_diff(a)),
extension: decoder.next_field_diff(&obj.extension, |dec, a| {
dec.next_optional_diff(a, |dec| dec.next_uint(), |dec, &a| dec.next_uint_diff(a))
}),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Contact {
EmailContact(EmailContact),
PhoneContact(PhoneContact),
}
impl Default for Contact {
fn default() -> Self {
Contact::EmailContact(EmailContact::default())
}
}
impl Contact {
pub fn equals(&self, other: &Self) -> bool {
match (self, other) {
(Contact::EmailContact(a), Contact::EmailContact(b)) => a.equals(b),
(Contact::PhoneContact(a), Contact::PhoneContact(b)) => a.equals(b),
_ => false,
}
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
match self {
Contact::EmailContact(v) => {
encoder.push_enum(0, 1);
v.encode_into(encoder);
}
Contact::PhoneContact(v) => {
encoder.push_enum(1, 1);
v.encode_into(encoder);
}
}
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
Self::encode_diff_into(a, b, encoder);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
let same_type = std::mem::discriminant(a) == std::mem::discriminant(b);
encoder.push_boolean(same_type);
match b {
Contact::EmailContact(b_val) => {
if let Contact::EmailContact(a_val) = a {
EmailContact::encode_diff_into(a_val, b_val, encoder);
} else {
encoder.push_enum(0, 1);
b_val.encode_into(encoder);
}
}
Contact::PhoneContact(b_val) => {
if let Contact::PhoneContact(a_val) = a {
PhoneContact::encode_diff_into(a_val, b_val, encoder);
} else {
encoder.push_enum(1, 1);
b_val.encode_into(encoder);
}
}
}
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
let variant = decoder.next_enum(1);
match variant {
0 => Contact::EmailContact(EmailContact::decode_from(decoder)),
1 => Contact::PhoneContact(PhoneContact::decode_from(decoder)),
_ => panic!("Invalid Contact variant: {}", variant),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| Self::decode_diff_from(obj, decoder))
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
let same_type = decoder.next_boolean();
if same_type {
match obj {
Contact::EmailContact(v) => {
Contact::EmailContact(EmailContact::decode_diff_from(v, decoder))
}
Contact::PhoneContact(v) => {
Contact::PhoneContact(PhoneContact::decode_diff_from(v, decoder))
}
}
} else {
let variant = decoder.next_enum(1);
match variant {
0 => Contact::EmailContact(EmailContact::decode_from(decoder)),
1 => Contact::PhoneContact(PhoneContact::decode_from(decoder)),
_ => panic!("Invalid Contact variant: {}", variant),
}
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct User {
pub id: String,
pub name: String,
pub age: u64,
pub weight: f32,
pub married: bool,
#[serde(rename = "hairColor")]
pub hair_color: HairColor,
pub address: Option<Address>,
pub children: Vec<Box<User>>,
pub metadata: IndexMap<String, String>,
#[serde(rename = "preferredContact")]
pub preferred_contact: Option<Contact>,
}
impl Default for User {
fn default() -> Self {
Self {
id: String::new(),
name: String::new(),
age: 0,
weight: 0.0,
married: false,
hair_color: HairColor::default(),
address: None,
children: Vec::new(),
metadata: IndexMap::new(),
preferred_contact: None,
}
}
}
impl User {
pub fn equals(&self, other: &Self) -> bool {
self.id == other.id
&& self.name == other.name
&& self.age == other.age
&& delta_pack::equals_float(self.weight, other.weight)
&& self.married == other.married
&& self.hair_color == other.hair_color
&& delta_pack::equals_optional(&self.address, &other.address, |x, y| x.equals(y))
&& delta_pack::equals_array(&self.children, &other.children, |x, y| x.equals(y))
&& self.metadata == other.metadata
&& delta_pack::equals_optional(
&self.preferred_contact,
&other.preferred_contact,
|x, y| x.equals(y),
)
}
pub fn encode(&self) -> Vec<u8> {
Encoder::encode(|encoder| {
self.encode_into(encoder);
encoder.finish()
})
}
pub fn encode_into(&self, encoder: &mut Encoder) {
encoder.push_string(&self.id);
encoder.push_string(&self.name);
encoder.push_uint(self.age);
encoder.push_float(self.weight);
encoder.push_boolean(self.married);
encoder.push_enum(self.hair_color.to_u32(), 3);
encoder.push_optional(&self.address, |enc, item| item.encode_into(enc));
encoder.push_array(&self.children, |enc, item| item.encode_into(enc));
encoder.push_record(
&self.metadata,
|enc, item| enc.push_string(item),
|enc, item| enc.push_string(item),
);
encoder.push_optional(&self.preferred_contact, |enc, item| item.encode_into(enc));
}
pub fn encode_diff(a: &Self, b: &Self) -> Vec<u8> {
Encoder::encode(|encoder| {
encoder.push_object_diff(
a,
b,
|x, y| x.equals(y),
|enc| {
Self::encode_diff_into(a, b, enc);
},
);
encoder.finish()
})
}
pub fn encode_diff_into(a: &Self, b: &Self, encoder: &mut Encoder) {
encoder.push_field_diff(
&a.id,
&b.id,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.name,
&b.name,
|x, y| x == y,
|enc, a, b| enc.push_string_diff(a, b),
);
encoder.push_field_diff(
&a.age,
&b.age,
|x, y| x == y,
|enc, &a, &b| enc.push_uint_diff(a, b),
);
encoder.push_field_diff(
&a.weight,
&b.weight,
|x, y| delta_pack::equals_float(*x, *y),
|enc, &a, &b| enc.push_float_diff(a, b),
);
encoder.push_boolean_diff(a.married, b.married);
encoder.push_field_diff(
&a.hair_color,
&b.hair_color,
|x, y| x == y,
|enc, &a, &b| enc.push_enum_diff(a.to_u32(), b.to_u32(), 3),
);
encoder.push_field_diff(
&a.address,
&b.address,
|x, y| delta_pack::equals_optional(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| item.encode_into(enc),
|enc, a, b| Address::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.children,
&b.children,
|x, y| delta_pack::equals_array(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_array_diff(
a,
b,
|x, y| x.equals(y),
|enc, item| item.encode_into(enc),
|enc, a, b| User::encode_diff_into(a, b, enc),
)
},
);
encoder.push_field_diff(
&a.metadata,
&b.metadata,
|x, y| x == y,
|enc, a, b| {
enc.push_record_diff(
a,
b,
|x, y| x == y,
|enc, item| enc.push_string(item),
|enc, item| enc.push_string(item),
|enc, a, b| enc.push_string_diff(a, b),
)
},
);
encoder.push_field_diff(
&a.preferred_contact,
&b.preferred_contact,
|x, y| delta_pack::equals_optional(&x, &y, |x, y| x.equals(y)),
|enc, a, b| {
enc.push_optional_diff(
a,
b,
|enc, item| item.encode_into(enc),
|enc, a, b| Contact::encode_diff_into(a, b, enc),
)
},
);
}
pub fn decode(buf: &[u8]) -> Self {
Decoder::decode(buf, |decoder| Self::decode_from(decoder))
}
pub fn decode_from(decoder: &mut Decoder) -> Self {
Self {
id: decoder.next_string(),
name: decoder.next_string(),
age: decoder.next_uint(),
weight: decoder.next_float(),
married: decoder.next_boolean(),
hair_color: HairColor::from_u32(decoder.next_enum(3)),
address: decoder.next_optional(|dec| Address::decode_from(dec)),
children: decoder.next_array(|dec| Box::new(User::decode_from(dec))),
metadata: decoder.next_record(|dec| dec.next_string(), |dec| dec.next_string()),
preferred_contact: decoder.next_optional(|dec| Contact::decode_from(dec)),
}
}
pub fn decode_diff(obj: &Self, diff: &[u8]) -> Self {
Decoder::decode(diff, |decoder| {
decoder.next_object_diff(obj, |dec| Self::decode_diff_from(obj, dec))
})
}
pub fn decode_diff_from(obj: &Self, decoder: &mut Decoder) -> Self {
Self {
id: decoder.next_field_diff(&obj.id, |dec, a| dec.next_string_diff(a)),
name: decoder.next_field_diff(&obj.name, |dec, a| dec.next_string_diff(a)),
age: decoder.next_field_diff(&obj.age, |dec, &a| dec.next_uint_diff(a)),
weight: decoder.next_field_diff(&obj.weight, |dec, &a| dec.next_float_diff(a)),
married: decoder.next_boolean_diff(obj.married),
hair_color: decoder.next_field_diff(&obj.hair_color, |dec, &a| {
HairColor::from_u32(dec.next_enum_diff(a.to_u32(), 3))
}),
address: decoder.next_field_diff(&obj.address, |dec, a| {
dec.next_optional_diff(
a,
|dec| Address::decode_from(dec),
|dec, a| Address::decode_diff_from(a, dec),
)
}),
children: decoder.next_field_diff(&obj.children, |dec, a| {
dec.next_array_diff(
a,
|dec| Box::new(User::decode_from(dec)),
|dec, a| Box::new(User::decode_diff_from(a, dec)),
)
}),
metadata: decoder.next_field_diff(&obj.metadata, |dec, a| {
dec.next_record_diff(
a,
|dec| dec.next_string(),
|dec| dec.next_string(),
|dec, a| dec.next_string_diff(a),
)
}),
preferred_contact: decoder.next_field_diff(&obj.preferred_contact, |dec, a| {
dec.next_optional_diff(
a,
|dec| Contact::decode_from(dec),
|dec, a| Contact::decode_diff_from(a, dec),
)
}),
}
}
}