Created
June 11, 2019 20:34
-
-
Save MightyPork/b79dd7feff685ec9da3d120026e83d01 to your computer and use it in GitHub Desktop.
example of custom serialize and deserialize in serde
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
Nice example. Thanks