Skip to content

Commit

Permalink
Implement (de)serialization of Option
Browse files Browse the repository at this point in the history
  • Loading branch information
gentoo90 committed Jan 6, 2025
1 parent 289f2e6 commit be5900a
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 24 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Current features:
* `u64` <=> `REG_QWORD`
* Iteration through key names and through values
* Transactions
* Transacted serialization of rust types into/from registry (only primitives, structures and maps for now)
* Transacted serialization of rust types into/from registry (only primitives, `Option`s, structures and maps for now)

## Usage

Expand Down Expand Up @@ -204,7 +204,7 @@ struct Size {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
coords: Coords,
coords: Option<Coords>,
size: Size,
}

Expand All @@ -219,6 +219,7 @@ struct Test {
t_struct: Rectangle,
t_map: HashMap<String, u32>,
t_string: String,
t_optional_string: Option<String>,
#[serde(rename = "")] // empty name becomes the (Default) value in the registry
t_char: char,
t_i8: i8,
Expand Down Expand Up @@ -248,11 +249,12 @@ fn main() -> Result<(), Box<dyn Error>> {
t_u64: 123_456_789_101_112,
t_usize: 1_234_567_891,
t_struct: Rectangle {
coords: Coords { x: 55, y: 77 },
coords: Some(Coords { x: 55, y: 77 }),
size: Size { w: 500, h: 300 },
},
t_map: map,
t_string: "test 123!".to_owned(),
t_optional_string: Some("test 456!".to_owned()),
t_char: 'a',
t_i8: -123,
t_i16: -2049,
Expand Down
6 changes: 3 additions & 3 deletions examples/map_key_serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Size {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
coords: Coords,
coords: Option<Coords>,
size: Size,
}

Expand All @@ -33,14 +33,14 @@ fn main() -> Result<(), Box<dyn Error>> {
v1.insert(
"first".to_owned(),
Rectangle {
coords: Coords { x: 55, y: 77 },
coords: Some(Coords { x: 55, y: 77 }),
size: Size { w: 500, h: 300 },
},
);
v1.insert(
"second".to_owned(),
Rectangle {
coords: Coords { x: 11, y: 22 },
coords: None,
size: Size { w: 1000, h: 600 },
},
);
Expand Down
6 changes: 4 additions & 2 deletions examples/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Size {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
coords: Coords,
coords: Option<Coords>,
size: Size,
}

Expand All @@ -37,6 +37,7 @@ struct Test {
t_struct: Rectangle,
t_map: HashMap<String, u32>,
t_string: String,
t_optional_string: Option<String>,
#[serde(with = "serde_bytes")]
t_bytes: Vec<u8>,
#[serde(rename = "")] // empty name becomes the (Default) value in the registry
Expand Down Expand Up @@ -68,11 +69,12 @@ fn main() -> Result<(), Box<dyn Error>> {
t_u64: 123_456_789_101_112,
t_usize: 1_234_567_891,
t_struct: Rectangle {
coords: Coords { x: 55, y: 77 },
coords: Some(Coords { x: 55, y: 77 }),
size: Size { w: 500, h: 300 },
},
t_map: map,
t_string: "test 123!".to_owned(),
t_optional_string: Some("test 456!".to_owned()),
t_bytes: vec![0xDE, 0xAD, 0xBE, 0xEF],
t_char: 'a',
t_i8: -123,
Expand Down
4 changes: 2 additions & 2 deletions examples/transacted_serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct Size {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
coords: Coords,
coords: Option<Coords>,
size: Size,
}

Expand Down Expand Up @@ -70,7 +70,7 @@ fn main() -> Result<(), Box<dyn Error>> {
t_u64: 123_456_789_101_112,
t_usize: 1_234_567_891,
t_struct: Rectangle {
coords: Coords { x: 55, y: 77 },
coords: Some(Coords { x: 55, y: 77 }),
size: Size { w: 500, h: 300 },
},
t_map: map,
Expand Down
20 changes: 16 additions & 4 deletions src/decoder/serialization_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// may not be copied, modified, or distributed
// except according to those terms.
use super::{DecodeResult, Decoder, DecoderCursor, DecoderError, DECODER_SAM};
use crate::types::FromRegValue;
use crate::{types::FromRegValue, RegValue};
use serde::de::*;
use std::fmt;

Expand Down Expand Up @@ -176,9 +176,21 @@ impl<'de, 'a> Deserializer<'de> for &'a mut Decoder {
let v = {
use super::DecoderCursor::*;
match self.cursor {
FieldVal(_, ref name) => {
self.key.get_raw_value(name).map_err(DecoderError::IoError)
}
Start => return visitor.visit_some(&mut *self),
FieldVal(index, ref name) => self
.key
.get_raw_value(name)
.map_err(DecoderError::IoError)
.and_then(|v| match v {
RegValue {
vtype: crate::enums::RegType::REG_NONE,
..
} => {
self.cursor = DecoderCursor::Field(index + 1);
Err(DecoderError::DeserializerError("Found REG_NONE".to_owned()))
}
val => Ok(val),
}),
_ => Err(DecoderError::DeserializerError("Nothing found".to_owned())),
}
};
Expand Down
9 changes: 6 additions & 3 deletions src/encoder/serialization_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,14 @@ impl<'a, Tr: AsRef<Transaction>> Serializer for &'a mut Encoder<Tr> {
}

fn serialize_none(self) -> EncodeResult<Self::Ok> {
no_impl!("serialize_none")
match mem::replace(&mut self.state, Start) {
NextKey(..) => Ok(()),
Start => Err(EncoderError::NoFieldName),
}
}

fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> EncodeResult<Self::Ok> {
no_impl!("serialize_some")
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> EncodeResult<Self::Ok> {
value.serialize(self)
}

fn serialize_unit(self) -> EncodeResult<Self::Ok> {
Expand Down
27 changes: 20 additions & 7 deletions tests/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct Size {

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Rectangle {
coords: Coords,
coords: Option<Coords>,
size: Size,
}

Expand All @@ -35,9 +35,14 @@ struct AllFields {
t_u32: u32,
t_u64: u64,
t_usize: usize,
t_struct: Rectangle,
t_rect_no_coords: Rectangle,
t_rect_with_coords: Rectangle,
t_string: String,
t_map: HashMap<String, HashMap<String, u32>>,
t_optional_u32_none: Option<u32>,
t_optional_u32_some: Option<u32>,
t_optional_map_none: Option<HashMap<String, u32>>,
t_optional_map_some: Option<HashMap<String, u32>>,
t_i8: i8,
t_i16: i16,
t_i32: i32,
Expand All @@ -63,7 +68,7 @@ impl AllFields {
k2.insert("val3".to_owned(), 1024);

let mut map = HashMap::new();
map.insert("key1".to_owned(), k1);
map.insert("key1".to_owned(), k1.clone());
map.insert("key2".to_owned(), k2);

AllFields {
Expand All @@ -73,11 +78,19 @@ impl AllFields {
t_u32: 123_456_789,
t_u64: 123_456_789_101_112,
t_usize: 1_234_567_891,
t_struct: Rectangle {
coords: Coords { x: 55, y: 77 },
t_rect_no_coords: Rectangle {
coords: None,
size: Size { w: 320, h: 240 },
},
t_rect_with_coords: Rectangle {
coords: Some(Coords { x: 55, y: 77 }),
size: Size { w: 500, h: 300 },
},
t_map: map,
t_optional_u32_none: None,
t_optional_u32_some: Some(1234),
t_optional_map_none: None,
t_optional_map_some: Some(k1),
t_string: "Test123 \n$%^&|+-*/\\()".to_owned(),
t_i8: -123,
t_i16: -2049,
Expand All @@ -95,7 +108,7 @@ impl AllFields {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct SomeFields {
t_usize: usize,
t_struct: Rectangle,
t_rect_no_coords: Rectangle,
t_string: String,
t_u32: Option<u32>,
t_none: Option<u32>,
Expand All @@ -105,7 +118,7 @@ impl PartialEq<AllFields> for SomeFields {
fn eq(&self, other: &AllFields) -> bool {
*self.t_string == other.t_string
&& self.t_usize == other.t_usize
&& self.t_struct == other.t_struct
&& self.t_rect_no_coords == other.t_rect_no_coords
&& self.t_u32 == Some(other.t_u32)
&& self.t_none.is_none()
}
Expand Down

0 comments on commit be5900a

Please sign in to comment.