use deser::de::{DeserializeDriver, DeserializeOwned};
use deser::ser::SerializeDriver;
use deser::{Deserialize, Event, Serialize};
fn without_len(event: deser::Event<'static>) -> deser::Event<'static> {
match event {
deser::Event::MapStart(shape) => {
deser::Event::MapStart(deser::ContainerShape::new().with_order(shape.order()))
}
deser::Event::SeqStart(shape) => {
deser::Event::SeqStart(deser::ContainerShape::new().with_order(shape.order()))
}
event => event,
}
}
fn deserialize<T: DeserializeOwned>(events: Vec<Event<'_>>) -> T {
let mut out = None;
{
let mut driver = DeserializeDriver::new(&mut out);
for event in events {
driver.emit(event).unwrap();
}
}
out.unwrap()
}
fn serialize<T: Serialize>(value: &T) -> Vec<Event<'static>> {
let mut rv = Vec::new();
let mut driver = SerializeDriver::new(value);
while let Some((event, _, _)) = driver.next().unwrap() {
rv.push(without_len(event.to_static()));
}
rv
}
pub trait Kind: 'static {
type Value;
}
#[derive(Debug, PartialEq)]
pub struct Text;
impl Kind for Text {
type Value = String;
}
#[test]
fn test_directional_bounds() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(
serialize_bound(K::Value: Serialize),
deserialize_bound(K::Value: Deserialize<'de>)
)]
struct Holder<K: Kind> {
value: K::Value,
}
let events = serialize(&Holder::<Text> { value: "x".into() });
assert_eq!(
events,
vec![
Event::map_start(),
"value".into(),
"x".into(),
Event::MapEnd
]
);
assert_eq!(
deserialize::<Holder<Text>>(events),
Holder { value: "x".into() }
);
}
#[test]
fn test_shared_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(bound(K::Value: Serialize + DeserializeOwned))]
struct Holder<K: Kind> {
value: K::Value,
}
let events = serialize(&Holder::<Text> { value: "x".into() });
assert_eq!(
deserialize::<Holder<Text>>(events),
Holder { value: "x".into() }
);
}
#[test]
fn test_empty_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(bound())]
struct Holder<K: Kind>
where
K::Value: Serialize + DeserializeOwned,
{
value: K::Value,
}
let events = serialize(&Holder::<Text> { value: "x".into() });
assert_eq!(
deserialize::<Holder<Text>>(events),
Holder { value: "x".into() }
);
}
#[test]
fn test_newtype_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(bound(K::Value: Serialize + DeserializeOwned))]
struct Holder<K: Kind>(K::Value);
let events = serialize(&Holder::<Text>("x".into()));
assert_eq!(events, vec!["x".into()]);
assert_eq!(deserialize::<Holder<Text>>(events), Holder("x".into()));
}
#[test]
fn test_enum_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(tag = "type", bound(K::Value: Serialize + DeserializeOwned, V: Serialize + DeserializeOwned))]
enum Message<K: Kind, V> {
Text { value: K::Value },
Other { other: V },
Empty,
}
for message in [
Message::<Text, u32>::Text { value: "x".into() },
Message::Other { other: 42 },
Message::Empty,
] {
let events = serialize(&message);
assert_eq!(deserialize::<Message<Text, u32>>(events), message);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(bound(K::Value: Serialize + DeserializeOwned, V: Serialize + DeserializeOwned))]
enum External<K: Kind, V> {
Text { value: K::Value },
Tuple(K::Value, V),
}
for message in [
External::<Text, u32>::Text { value: "x".into() },
External::Tuple("y".into(), 23),
] {
let events = serialize(&message);
assert_eq!(deserialize::<External<Text, u32>>(events), message);
}
}
#[test]
fn test_field_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Holder<K: Kind, V> {
#[deser(
serialize_bound(K::Value: Serialize),
deserialize_bound(K::Value: Deserialize<'de>)
)]
value: K::Value,
other: V,
}
let value = Holder::<Text, u32> {
value: "x".into(),
other: 1,
};
let events = serialize(&value);
assert_eq!(deserialize::<Holder<Text, u32>>(events), value);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Tuple<K: Kind>(
#[deser(bound(K::Value: Serialize + DeserializeOwned))] K::Value,
u32,
);
let value = Tuple::<Text>("x".into(), 1);
let events = serialize(&value);
assert_eq!(deserialize::<Tuple<Text>>(events), value);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(tag = "type")]
enum Message<K: Kind> {
Text {
#[deser(bound(K::Value: Serialize + DeserializeOwned))]
value: K::Value,
},
Pair(
#[deser(bound(K::Value: Serialize + DeserializeOwned))] K::Value,
#[deser(skip)] u32,
),
}
let message = Message::<Text>::Text { value: "x".into() };
let events = serialize(&message);
assert_eq!(deserialize::<Message<Text>>(events), message);
}
#[test]
fn test_variant_bound() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[deser(tag = "type", content = "content")]
enum Message<K: Kind, V> {
#[deser(
serialize_bound(K::Value: Serialize),
deserialize_bound(K::Value: Deserialize<'de>)
)]
Text {
value: K::Value,
#[deser(skip)]
marker: std::marker::PhantomData<K>,
},
#[deser(
serialize_bound(K::Value: Serialize),
deserialize_bound(K::Value: Deserialize<'de>)
)]
Pair(K::Value, K::Value),
Other {
other: V,
},
Empty,
}
for message in [
Message::<Text, u32>::Text {
value: "x".into(),
marker: std::marker::PhantomData,
},
Message::Pair("a".into(), "b".into()),
Message::Other { other: 42 },
Message::Empty,
] {
let events = serialize(&message);
assert_eq!(deserialize::<Message<Text, u32>>(events), message);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum External<K: Kind> {
#[deser(bound(K::Value: Serialize + DeserializeOwned))]
Newtype(K::Value),
#[deser(bound(K::Value: Serialize + DeserializeOwned))]
Struct { value: K::Value },
}
for message in [
External::<Text>::Newtype("x".into()),
External::Struct { value: "y".into() },
] {
let events = serialize(&message);
assert_eq!(deserialize::<External<Text>>(events), message);
}
}
#[test]
fn test_variant_bound_with_adapter() {
use deser::adapters::DisplayFromStr;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum Message<K: Kind> {
#[deser(
as = (DisplayFromStr, DisplayFromStr),
bound(
K::Value: std::fmt::Display + std::str::FromStr + Send + Sync,
<K::Value as std::str::FromStr>::Err: std::fmt::Display,
)
)]
Pair(K::Value, K::Value),
}
let message = Message::<Text>::Pair("a".into(), "b".into());
let events = serialize(&message);
assert_eq!(deserialize::<Message<Text>>(events), message);
}