Skip to content

Instantly share code, notes, and snippets.

@vmx
Created January 12, 2022 22:56
Show Gist options
  • Save vmx/b7bfd7fa276fecc4fc8789109572963b to your computer and use it in GitHub Desktop.
Save vmx/b7bfd7fa276fecc4fc8789109572963b to your computer and use it in GitHub Desktop.
Trying to serialize a CID as enum
use std::fmt;
use serde::{de, ser, Deserialize, Serialize};
pub const ENUM_NAME: &str = "enumname";
pub const ENUM_VARIANT_NAME: &str = "enumvariantname";
//#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[derive(Debug, PartialEq)]
pub struct Cid(String);
#[derive(Debug, PartialEq, Serialize)]
pub enum WrappedCid {
Cid(String),
}
impl ser::Serialize for Cid {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_newtype_variant(ENUM_NAME, 0, ENUM_VARIANT_NAME, &self.0)
}
}
pub struct CidVisitor;
impl<'de> de::Visitor<'de> for CidVisitor {
type Value = Cid;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "a valid CID in bytes, wrapped in an enum")
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: de::EnumAccess<'de>,
{
println!("vmx: rust cid: de visit enum");
match data.variant() {
Ok((ENUM_VARIANT_NAME, variant)) => {
println!("vmx: that works?");
de::VariantAccess::newtype_variant(variant).map(Cid)
},
_ => Err(de::Error::custom("Cannot deserialize CID")),
}
}
}
impl<'de> de::Deserialize<'de> for Cid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
println!("vmx: rust cid: deserialize");
//deserializer.deserialize_enum(ENUM_NAME, &[ENUM_VARIANT_NAME], CidVisitor)
deserializer.deserialize_enum(ENUM_NAME, &[ENUM_VARIANT_NAME], CidVisitor)
}
}
//#[doc(hidden)]
//#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
//const _: () = {
// #[allow(unused_extern_crates, clippy::useless_attribute)]
// extern crate serde as _serde;
// #[automatically_derived]
// impl<'de> _serde::Deserialize<'de> for WrappedCid {
// fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
// where
// __D: _serde::Deserializer<'de>,
// {
// #[allow(non_camel_case_types)]
// enum __Field {
// __field0,
// }
// struct __FieldVisitor;
// impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
// type Value = __Field;
// fn expecting(
// &self,
// __formatter: &mut _serde::__private::Formatter,
// ) -> _serde::__private::fmt::Result {
// _serde::__private::Formatter::write_str(__formatter, "variant identifier")
// }
// fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
// where
// __E: _serde::de::Error,
// {
// match __value {
// 0u64 => _serde::__private::Ok(__Field::__field0),
// _ => _serde::__private::Err(_serde::de::Error::invalid_value(
// _serde::de::Unexpected::Unsigned(__value),
// &"variant index 0 <= i < 1",
// )),
// }
// }
// fn visit_str<__E>(
// self,
// __value: &str,
// ) -> _serde::__private::Result<Self::Value, __E>
// where
// __E: _serde::de::Error,
// {
// match __value {
// "Cid" => _serde::__private::Ok(__Field::__field0),
// _ => _serde::__private::Err(_serde::de::Error::unknown_variant(
// __value, VARIANTS,
// )),
// }
// }
// fn visit_bytes<__E>(
// self,
// __value: &[u8],
// ) -> _serde::__private::Result<Self::Value, __E>
// where
// __E: _serde::de::Error,
// {
// match __value {
// b"Cid" => _serde::__private::Ok(__Field::__field0),
// _ => {
// let __value = &_serde::__private::from_utf8_lossy(__value);
// _serde::__private::Err(_serde::de::Error::unknown_variant(
// __value, VARIANTS,
// ))
// }
// }
// }
// }
// impl<'de> _serde::Deserialize<'de> for __Field {
// #[inline]
// fn deserialize<__D>(
// __deserializer: __D,
// ) -> _serde::__private::Result<Self, __D::Error>
// where
// __D: _serde::Deserializer<'de>,
// {
// _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
// }
// }
// struct __Visitor<'de> {
// marker: _serde::__private::PhantomData<WrappedCid>,
// lifetime: _serde::__private::PhantomData<&'de ()>,
// }
// impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
// type Value = WrappedCid;
// fn expecting(
// &self,
// __formatter: &mut _serde::__private::Formatter,
// ) -> _serde::__private::fmt::Result {
// _serde::__private::Formatter::write_str(__formatter, "enum WrappedCid")
// }
// fn visit_enum<__A>(
// self,
// __data: __A,
// ) -> _serde::__private::Result<Self::Value, __A::Error>
// where
// __A: _serde::de::EnumAccess<'de>,
// {
// //match match _serde::de::EnumAccess::variant(__data) {
// // _serde::__private::Ok(__val) => __val,
// // _serde::__private::Err(__err) => {
// // return _serde::__private::Err(__err);
// // }
// //} {
// // (__Field::__field0, __variant) => _serde::__private::Result::map(
// // _serde::de::VariantAccess::newtype_variant::<String>(__variant),
// // WrappedCid::Cid,
// // ),
// //}
// let (foo, bar): (__Field, _) = serde::de::EnumAccess::variant(__data)?;
// Ok(WrappedCid::Cid("yay".to_string()))
// }
// }
// const VARIANTS: &'static [&'static str] = &["Cid"];
// _serde::Deserializer::deserialize_enum(
// __deserializer,
// "WrappedCid",
// VARIANTS,
// __Visitor {
// marker: _serde::__private::PhantomData::<WrappedCid>,
// lifetime: _serde::__private::PhantomData,
// },
// )
// }
// }
//};
fn main() {
//let cid = WrappedCid::Cid("bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy".to_string());
let cid = Cid("bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy".to_string());
let json = serde_json::to_string(&cid).unwrap();
println!("vmx: serialized enum: {}", json);
let cid2 = serde_json::from_str(&json).unwrap();
assert_eq!(cid, cid2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment