Skip to content

Instantly share code, notes, and snippets.

@webern
Forked from MightyPork/custom-serde.rs
Created October 26, 2021 21:54
Show Gist options
  • Save webern/548d000a13939c3dfe67d957e2b6ec44 to your computer and use it in GitHub Desktop.
Save webern/548d000a13939c3dfe67d957e2b6ec44 to your computer and use it in GitHub Desktop.
example of custom serialize and deserialize in serde
use serde::ser::SerializeMap;
use serde::{Serialize, Serializer, de::Visitor, de::MapAccess, Deserialize, Deserializer};
use std::fmt;
#[derive(Debug)]
struct Custom(String, u32);
impl Serialize for Custom {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_map(Some(2))?;
seq.serialize_entry("first", &self.0)?;
seq.serialize_entry("second", &self.1)?;
seq.end()
}
}
impl<'de> Deserialize<'de> for Custom {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
//deserializer.deserialize_any(CustomVisitor)
deserializer.deserialize_map(CustomVisitor)
}
}
struct CustomVisitor;
impl<'de> Visitor<'de> for CustomVisitor {
type Value = Custom;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map with keys 'first' and 'second'")
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>
{
let mut first = None;
let mut second = None;
while let Some(k) = map.next_key::<&str>()? {
if k == "first" {
first = Some(map.next_value()?);
}
else if k == "second" {
second = Some(map.next_value()?);
}
else {
return Err(serde::de::Error::custom(&format!("Invalid key: {}", k)));
}
}
if first.is_none() || second.is_none() {
return Err(serde::de::Error::custom("Missing first or second"));
}
Ok(Custom(first.unwrap(), second.unwrap()))
}
}
fn main() {
let stru = Custom("lala".to_string(), 123);
println!("Orig {:?}", stru);
let serialized = serde_json::to_string(&stru).expect("err ser");
println!("Seri {}", serialized);
let unse : Custom = serde_json::from_str(&serialized).expect("err unser");
println!("New {:?}", unse);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment