use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_cbor::tags::Tagged;
use serde_cbor::Value;
use serde_derive::{Deserialize, Serialize};
use std::error::Error;
#[derive(Debug, PartialEq)]
struct Date(String);
impl Serialize for Date {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
Tagged::new(Some(0), &self.0).serialize(s)
}
}
impl<'de> Deserialize<'de> for Date {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let tagged = Tagged::<String>::deserialize(deserializer)?;
match tagged.tag {
Some(0) | None => Ok(Date(tagged.value)),
Some(_) => Err(serde::de::Error::custom("unexpected tag")),
}
}
}
#[derive(Debug, PartialEq)]
struct Uri(String);
impl Serialize for Uri {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
Tagged::new(Some(32), &self.0).serialize(s)
}
}
impl<'de> Deserialize<'de> for Uri {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let tagged = Tagged::<String>::deserialize(deserializer)?;
match tagged.tag {
Some(0) | None => Ok(Uri(tagged.value)),
Some(_) => Err(serde::de::Error::custom("unexpected tag")),
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Bookmark {
title: String,
link: Uri,
created: Date,
}
fn main() -> Result<(), Box<dyn Error>> {
let bookmark = Bookmark {
title: "The Example Domain".into(),
link: Uri("http://example.org/".into()),
created: Date("2003-12-13T18:30:02Z".into()),
};
let bytes1 = serde_cbor::to_vec(&bookmark)?;
let value1: Value = serde_cbor::from_slice(&bytes1)?;
println!("{:?}", value1);
let bytes2 = serde_cbor::to_vec(&value1)?;
let value2: Value = serde_cbor::from_slice(&bytes2)?;
println!("{:?}", value2);
let result: Bookmark = serde_cbor::from_slice(&bytes2)?;
assert_eq!(value1, value2);
assert_eq!(bookmark, result);
Ok(())
}