extern crate erased_serde;
extern crate serde;
extern crate serde_json;
extern crate serde_tagged;
#[macro_use]
extern crate serde_derive;
use serde_tagged::de::external::deserialize;
use serde_tagged::de::{BoxFnSeed, SeedFactory, WithTag, WithoutTag};
use std::collections::BTreeMap;
use serde::Deserialize;
trait TypeId: std::fmt::Debug {
fn type_id(&self) -> &'static str;
}
#[derive(Debug, Serialize, Deserialize)]
struct Message {
id: u32,
text: String,
}
impl TypeId for Message {
fn type_id(&self) -> &'static str {
"Message"
}
}
impl TypeId for i64 {
fn type_id(&self) -> &'static str {
"i64"
}
}
fn main() {
let mut buf_msg = Vec::new();
{
let value = Message {
id: 0,
text: "Hello World".to_owned(),
};
let mut serializer = serde_json::Serializer::new(&mut buf_msg);
serde_tagged::ser::external::serialize(&mut serializer, value.type_id(), &value).unwrap();
}
let mut buf_i64 = Vec::new();
{
let value: i64 = 42;
let mut serializer = serde_json::Serializer::new(&mut buf_i64);
serde_tagged::ser::external::serialize(&mut serializer, value.type_id(), &value).unwrap();
}
println!("-- Serialize data --------------------------------------------------------------");
println!("Serialized: {}", std::str::from_utf8(&buf_msg).unwrap());
println!("Serialized: {}", std::str::from_utf8(&buf_i64).unwrap());
println!();
println!("-- Deserialize known value without tag -----------------------------------------");
let mut de = serde_json::Deserializer::from_slice(&buf_msg);
let v: Message = deserialize::<&str, _, _>(&mut de, WithoutTag::new()).unwrap();
println!("Deserialized: value: {:?}", v);
let mut de = serde_json::Deserializer::from_slice(&buf_i64);
let v: i64 = deserialize::<&str, _, _>(&mut de, WithoutTag::new()).unwrap();
println!("Deserialized: value: {:?}", v);
println!();
println!("-- Deserialize known value with tag --------------------------------------------");
let mut de = serde_json::Deserializer::from_slice(&buf_msg);
let (t, v): (&str, Message) = deserialize(&mut de, WithTag::new()).unwrap();
println!("Deserialized: tag: {:?}, value: {:?}", t, v);
let mut de = serde_json::Deserializer::from_slice(&buf_i64);
let (t, v): (&str, i64) = deserialize(&mut de, WithTag::new()).unwrap();
println!("Deserialized: tag: {:?}, value: {:?}", t, v);
println!();
println!("-- Deserialize trait-object with TypeSeedFactory -------------------------------");
let mut de = serde_json::Deserializer::from_slice(&buf_msg);
let v = deserialize(&mut de, TypeSeedFactory).unwrap();
println!("Deserialized: value: {:?}", v);
let mut de = serde_json::Deserializer::from_slice(&buf_i64);
let v = deserialize(&mut de, TypeSeedFactory).unwrap();
println!("Deserialized: value: {:?}", v);
println!();
println!("-- Deserialize trait-object with (BTree)Map ------------------------------------");
type RegSeedFn = BoxFnSeed<Box<dyn TypeId>>;
let mut seeds = BTreeMap::new();
seeds.insert("Message".to_owned(), RegSeedFn::new(deserialize_msg));
seeds.insert("i64".to_owned(), RegSeedFn::new(deserialize_i64));
fn deserialize_msg<'de>(
de: &mut dyn erased_serde::Deserializer<'de>,
) -> Result<Box<dyn TypeId>, erased_serde::Error> {
Ok(Box::new(Message::deserialize(de)?))
}
fn deserialize_i64<'de>(
de: &mut dyn erased_serde::Deserializer<'de>,
) -> Result<Box<dyn TypeId>, erased_serde::Error> {
Ok(Box::new(i64::deserialize(de)?))
}
let mut de = serde_json::Deserializer::from_slice(&buf_msg);
let v = deserialize(&mut de, &seeds).unwrap();
println!("Deserialized: value: {:?}", v);
let mut de = serde_json::Deserializer::from_slice(&buf_i64);
let v = deserialize(&mut de, &seeds).unwrap();
println!("Deserialized: value: {:?}", v);
}
struct TypeSeedFactory;
impl<'de> SeedFactory<'de, &'de str> for TypeSeedFactory {
type Value = Box<dyn TypeId>;
type Seed = TypeSeed<'de>;
fn seed<E>(self, tag: &'de str) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
Ok(TypeSeed::new(tag))
}
}
struct TypeSeed<'de> {
tag: &'de str,
}
impl<'de> TypeSeed<'de> {
fn new(tag: &'de str) -> Self {
TypeSeed { tag }
}
}
impl<'de> serde::de::DeserializeSeed<'de> for TypeSeed<'de> {
type Value = Box<dyn TypeId>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
match self.tag {
"Message" => Ok(Box::new(Message::deserialize(deserializer)?)),
"i64" => Ok(Box::new(i64::deserialize(deserializer)?)),
tag => Err(serde::de::Error::unknown_variant(tag, &["Message"])),
}
}
}