Skip to content

Instantly share code, notes, and snippets.

@erickt
Created February 27, 2016 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erickt/535f3867c70db235bad7 to your computer and use it in GitHub Desktop.
Save erickt/535f3867c70db235bad7 to your computer and use it in GitHub Desktop.
Compiling foo v0.1.0 (file:///private/tmp/foo)
Running `target/debug/foo`
{"map":{"0":"zero","1":"one"}}
Foo { map: {0: "zero", 1: "one"} }
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate serde_json;
use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::str::FromStr;
fn serialize_map<T, S>(value: &BTreeMap<u64, T>, serializer: &mut S) -> Result<(), S::Error>
where T: serde::Serialize,
S: serde::Serializer,
{
let visitor = serde::ser::impls::MapIteratorVisitor::new(
value.iter().map(|(key, value)| (key.to_string(), value)),
Some(value.len()),
);
serializer.serialize_map(visitor)
}
fn deserialize_map<T, D>(deserializer: &mut D) -> Result<BTreeMap<u64, T>, D::Error>
where T: serde::Deserialize,
D: serde::Deserializer,
{
use serde::de::{Visitor, Error};
struct MapVisitor<T>(PhantomData<T>);
impl<T> serde::de::Visitor for MapVisitor<T>
where T: serde::Deserialize,
{
type Value = BTreeMap<u64, T>;
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> Result<Self::Value, V::Error>
where V: serde::de::MapVisitor,
{
let mut map = BTreeMap::new();
while let Some((key, value)) = try!(visitor.visit()) {
let key: String = key;
let key = match u64::from_str(&key) {
Ok(key) => key,
Err(_) => { return Err(V::Error::invalid_value("key must be a u64")); }
};
map.insert(key, value);
}
try!(visitor.end());
Ok(map)
}
}
deserializer.deserialize_map(MapVisitor(PhantomData))
}
#[derive(Debug, Serialize, Deserialize)]
struct Foo {
#[serde(serialize_with="serialize_map", deserialize_with="deserialize_map")]
map: BTreeMap<u64, String>,
}
fn main() {
let mut map = BTreeMap::new();
map.insert(0u64, String::from("zero"));
map.insert(1u64, String::from("one"));
let foo = Foo {
map: map,
};
let s = serde_json::to_string(&foo).unwrap();
println!("{}", s);
let foo: Foo = serde_json::from_str(&s).unwrap();
println!("{:?}", foo);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment