From 8391417b197448ee67ca6ed85522aa38043a5728 Mon Sep 17 00:00:00 2001 From: Arnaud de Bossoreille Date: Tue, 16 Jan 2024 16:41:05 +0100 Subject: [PATCH] Serialize record as tuple --- machin/Cargo.toml | 1 + machin/src/main.rs | 120 ++++++++++++++++++++++++++- truc/src/generator/fragment/serde.rs | 19 +++-- 3 files changed, 132 insertions(+), 8 deletions(-) diff --git a/machin/Cargo.toml b/machin/Cargo.toml index 2d2a260..9acd2a9 100644 --- a/machin/Cargo.toml +++ b/machin/Cargo.toml @@ -6,6 +6,7 @@ rust-version = "1.56.1" [dependencies] assert_matches = "1" +bincode = "1" machin_data = { path = "../machin_data" } serde = "1" serde_json = "1" diff --git a/machin/src/main.rs b/machin/src/main.rs index 520663f..041d0e6 100644 --- a/machin/src/main.rs +++ b/machin/src/main.rs @@ -139,9 +139,11 @@ fn machin() { record_5.datum_array_of_strings(), &["Hello".to_string(), "World".to_string()] ); + + println!("machin OK"); } -fn serialize_deserialize() { +fn serialize_deserialize_json() { use crate::truc::serialize_deserialize::*; let record_0 = Record0::new(UnpackedRecord0 { @@ -158,6 +160,10 @@ fn serialize_deserialize() { ] { assert_eq!(*record_0.datum_a(), 1); assert_eq!(*record_0.datum_b(), 2); + let UnpackedRecord0 { + datum_a: _, + datum_b: _, + } = record_0.unpack(); } let record_1 = Record1::from((record_0, UnpackedRecordIn1 { datum_c: 3 })); @@ -172,6 +178,11 @@ fn serialize_deserialize() { assert_eq!(*record_1.datum_a(), 1); assert_eq!(*record_1.datum_b(), 2); assert_eq!(*record_1.datum_c(), 3); + let UnpackedRecord1 { + datum_a: _, + datum_b: _, + datum_c: _, + } = record_1.unpack(); } let record_2 = Record2::from((record_1, UnpackedRecordIn2 {})); @@ -185,6 +196,10 @@ fn serialize_deserialize() { ] { assert_eq!(*record_2.datum_b(), 2); assert_eq!(*record_2.datum_c(), 3); + let UnpackedRecord2 { + datum_b: _, + datum_c: _, + } = record_2.unpack(); } let record_3 = Record3::from(( @@ -204,11 +219,112 @@ fn serialize_deserialize() { assert_eq!(*record_3.datum_b(), 2); assert_eq!(*record_3.datum_c(), 3); assert_eq!(*record_3.datum_v(), vec![2, 12, 42]); + let UnpackedRecord3 { + datum_b: _, + datum_c: _, + datum_v: _, + } = record_3.unpack(); + } + + let record_4 = Record4::from((record_3, UnpackedRecordIn4 {})); + + let record_4_json = serde_json::to_value(&record_4).unwrap(); + assert_eq!(record_4_json, json!([])); + + for record_4 in [ + serde_json::from_str::(&record_4_json.to_string()).unwrap(), + serde_json::from_value::(record_4_json).unwrap(), + ] { + let UnpackedRecord4 {} = record_4.unpack(); + } + + println!("serialize_deserialize_json OK"); +} + +fn serialize_deserialize_bincode() { + use crate::truc::serialize_deserialize::*; + + let record_0 = Record0::new(UnpackedRecord0 { + datum_a: 1, + datum_b: 2, + }); + + let record_0_bincode = bincode::serialize(&record_0).unwrap(); + + { + let record_0 = bincode::deserialize::(&record_0_bincode).unwrap(); + assert_eq!(*record_0.datum_a(), 1); + assert_eq!(*record_0.datum_b(), 2); + let UnpackedRecord0 { + datum_a: _, + datum_b: _, + } = record_0.unpack(); + } + + let record_1 = Record1::from((record_0, UnpackedRecordIn1 { datum_c: 3 })); + + let record_1_bincode = bincode::serialize(&record_1).unwrap(); + + { + let record_1 = bincode::deserialize::(&record_1_bincode).unwrap(); + assert_eq!(*record_1.datum_a(), 1); + assert_eq!(*record_1.datum_b(), 2); + assert_eq!(*record_1.datum_c(), 3); + let UnpackedRecord1 { + datum_a: _, + datum_b: _, + datum_c: _, + } = record_1.unpack(); + } + + let record_2 = Record2::from((record_1, UnpackedRecordIn2 {})); + + let record_2_bincode = bincode::serialize(&record_2).unwrap(); + + { + let record_2 = bincode::deserialize::(&record_2_bincode).unwrap(); + assert_eq!(*record_2.datum_b(), 2); + assert_eq!(*record_2.datum_c(), 3); + let UnpackedRecord2 { + datum_b: _, + datum_c: _, + } = record_2.unpack(); + } + + let record_3 = Record3::from(( + record_2, + UnpackedRecordIn3 { + datum_v: vec![2, 12, 42], + }, + )); + + let record_3_bincode = bincode::serialize(&record_3).unwrap(); + + { + let record_3 = bincode::deserialize::(&record_3_bincode).unwrap(); + assert_eq!(*record_3.datum_b(), 2); + assert_eq!(*record_3.datum_c(), 3); + assert_eq!(*record_3.datum_v(), vec![2, 12, 42]); + let UnpackedRecord3 { + datum_b: _, + datum_c: _, + datum_v: _, + } = record_3.unpack(); } + + let record_4 = Record4::from((record_3, UnpackedRecordIn4 {})); + + let record_4_bincode = bincode::serialize(&record_4).unwrap(); + + let record_4 = bincode::deserialize::(&record_4_bincode).unwrap(); + let UnpackedRecord4 {} = record_4.unpack(); + + println!("serialize_deserialize_bincode OK"); } fn main() -> Result<(), String> { machin(); - serialize_deserialize(); + serialize_deserialize_json(); + serialize_deserialize_bincode(); Ok(()) } diff --git a/truc/src/generator/fragment/serde.rs b/truc/src/generator/fragment/serde.rs index 1139712..6d3d13e 100644 --- a/truc/src/generator/fragment/serde.rs +++ b/truc/src/generator/fragment/serde.rs @@ -23,14 +23,20 @@ impl SerdeImplGenerator { .bound("S", "serde::Serializer"); if !record_spec.data.is_empty() { - serialize_fn.line("let mut seq = serializer.serialize_seq(None)?;"); + serialize_fn.line(format!( + "let mut tuple = serializer.serialize_tuple({})?;", + record_spec.data.len() + )); } else { - serialize_fn.line("let seq = serializer.serialize_seq(None)?;"); + serialize_fn.line("let tuple = serializer.serialize_tuple(0)?;"); } for datum in &record_spec.data { - serialize_fn.line(format!("seq.serialize_element(self.{}())?;", datum.name())); + serialize_fn.line(format!( + "tuple.serialize_element(self.{}())?;", + datum.name() + )); } - serialize_fn.line("seq.end()"); + serialize_fn.line("tuple.end()"); } fn generate_visitor(record_spec: &RecordSpec, deserialize_fn: &mut Function) { @@ -122,7 +128,8 @@ impl SerdeImplGenerator { Self::generate_visitor(record_spec, deserialize_fn); deserialize_fn.line(&format!( - "deserializer.deserialize_seq(RecordVisitor::<{}>)", + "deserializer.deserialize_tuple({}, RecordVisitor::<{}>)", + record_spec.data.len(), CAP )); } @@ -130,7 +137,7 @@ impl SerdeImplGenerator { impl FragmentGenerator for SerdeImplGenerator { fn imports(&self, scope: &mut Scope) { - scope.import("serde::ser", "SerializeSeq"); + scope.import("serde::ser", "SerializeTuple"); scope.import("serde::de", "Error"); }