Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
- use serde::ser::{Serialize, SerializeStruct, Serializer};
- use serde_derive::*;
- use std::collections::BTreeSet;
- use std::fmt;
- use failure::Error;
- fn main() -> Result<(), Error> {
- let mut t = BTreeSet::new();
- t.insert(FieldType::A(34));
- t.insert(FieldType::F(true));
- let tt = Wrap(t);
- println!("in {:?}", tt);
- let s = serde_json::to_string(&tt)?;
- println!("to json '{}'", s);
- let ttt: Wrap = serde_json::from_str(&s)?;
- println!("from json {:?}", ttt);
- // let bson = bson::to_bson(&t);
- // println!("Encoded bson: {:?}", bson);
- // let result: Wrap = bson::from_bson(bson?)?;
- // println!("Decode: bson {:?}", result);
- // assert_eq!(result, *msg);
- Ok(())
- }
- macro_rules! tagged_enum {
- ($name:ident { $( $variant:ident ( $content:ty ), )* }) => {
- #[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, PartialOrd, Ord)]
- enum $name {
- $(
- $variant($content),
- )*
- }
- #[derive(Debug, Eq, PartialEq, Hash, Clone, PartialOrd, Ord)]
- struct Wrap(BTreeSet<$name>);
- impl Serialize for Wrap {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer,
- {
- let mut state = serializer.serialize_struct(stringify!($name), self.0.len())?;
- for e in &self.0 {
- match e {
- $(
- $name::$variant(v) => state.serialize_field(stringify!($variant), &v)?,
- )*
- }
- }
- state.end()
- }
- }
- impl<'de> Deserialize<'de> for Wrap {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- #[derive(Deserialize, Debug)]
- #[serde(field_identifier)]
- enum Field {
- $(
- $variant,
- )*
- };
- struct WrapVisitor;
- impl<'de> Visitor<'de> for WrapVisitor {
- type Value = Wrap;
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("struct Wrap")
- }
- fn visit_seq<V>(self, mut seq: V) -> Result<Wrap, V::Error>
- where
- V: SeqAccess<'de>,
- {
- let mut s = BTreeSet::new();
- log::debug!("visit_seq");
- $(
- s.insert($name::$variant(seq.next_element()?.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?));
- )*
- Ok(Wrap(s))
- }
- fn visit_map<V>(self, mut map: V) -> Result<Wrap, V::Error>
- where
- V: MapAccess<'de>,
- {
- log::debug!("visit_map");
- let mut s = BTreeSet::new();
- while let Some(key) = map.next_key()? {
- log::debug!("{:?}", key);
- match key {
- $(
- Field::$variant => s.insert($name::$variant(map.next_value()?)),
- )*
- };
- }
- Ok(Wrap(s))
- }
- }
- const FIELDS: &'static [&'static str] = &[
- $(
- stringify!($variant),
- )*
- ];
- deserializer.deserialize_struct("Wrap", FIELDS, WrapVisitor)
- }
- }
- }
- }
- tagged_enum!(
- FieldType {
- A(u8),
- B(u16),
- C(u16),
- D(i32),
- E(bool),
- F(bool),
- G(i8),
- H(bool),
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement