-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathtests.rs
More file actions
155 lines (138 loc) · 5.63 KB
/
tests.rs
File metadata and controls
155 lines (138 loc) · 5.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use super::*;
#[test]
fn test_struct_info_roundtrip() {
let s = ItemEnum::Struct(Struct {
generics: Generics { params: vec![], where_predicates: vec![] },
kind: StructKind::Plain { fields: vec![], has_stripped_fields: false },
impls: vec![],
});
// JSON
let struct_json = serde_json::to_string(&s).unwrap();
let de_s = serde_json::from_str(&struct_json).unwrap();
assert_eq!(s, de_s);
// Bincode
let encoded: Vec<u8> = bincode::serialize(&s).unwrap();
let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap();
assert_eq!(s, decoded);
}
#[test]
fn test_union_info_roundtrip() {
let u = ItemEnum::Union(Union {
generics: Generics { params: vec![], where_predicates: vec![] },
has_stripped_fields: false,
fields: vec![],
impls: vec![],
});
// JSON
let union_json = serde_json::to_string(&u).unwrap();
let de_u = serde_json::from_str(&union_json).unwrap();
assert_eq!(u, de_u);
// Bincode
let encoded: Vec<u8> = bincode::serialize(&u).unwrap();
let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap();
assert_eq!(u, decoded);
}
#[cfg(feature = "rkyv_0_8")]
mod rkyv {
use std::fmt::Debug;
use rkyv::Archive;
use rkyv::api::high::{HighDeserializer, HighSerializer};
use rkyv::bytecheck::CheckBytes;
use rkyv::rancor::Strategy;
use rkyv::ser::allocator::ArenaHandle;
use rkyv::util::AlignedVec;
use rkyv::validation::Validator;
use rkyv::validation::archive::ArchiveValidator;
use rkyv::validation::shared::SharedValidator;
use crate::*;
#[test]
/// A test to exercise the (de)serialization roundtrip for a representative selection of types,
/// covering most of the rkyv-specific attributes we had to had.
fn test_rkyv_roundtrip() {
// Standard derives: a plain struct and union, mirroring the existing serde/bincode tests.
let s = ItemEnum::Struct(Struct {
generics: Generics { params: vec![], where_predicates: vec![] },
kind: StructKind::Plain { fields: vec![Id(1), Id(2)], has_stripped_fields: false },
impls: vec![Id(3)],
});
rkyv_roundtrip(&s);
let u = ItemEnum::Union(Union {
generics: Generics { params: vec![], where_predicates: vec![] },
has_stripped_fields: false,
fields: vec![Id(1)],
impls: vec![],
});
rkyv_roundtrip(&u);
// Extra trait derives, via rkyv(derive(PartialEq, Eq, PartialOrd, Ord, Hash)), on the archived type.
rkyv_roundtrip(&Id(99));
// Recursive cycle-breaking: `BorrowedRef` has omit_bounds on its `Box<Type>` field.
let ty = Type::BorrowedRef {
lifetime: Some("'a".to_string()),
is_mutable: false,
type_: Box::new(Type::Primitive("str".to_string())),
};
rkyv_roundtrip(&ty);
// `Slice` and `Tuple` are tuple-variant fields with omit_bounds on the unnamed field,
// which required special syntax (attribute inside the parentheses) to compile.
let ty = Type::Slice(Box::new(Type::Tuple(vec![
Type::Primitive("u32".to_string()),
Type::Generic("T".to_string()),
])));
rkyv_roundtrip(&ty);
// `Path` has serialize_bounds/deserialize_bounds and omit_bounds on its `args` field.
// `GenericArgs::AngleBracketed` exercises the full recursive chain: `Path` -> `GenericArgs` -> `GenericArg` -> `Type`.
let path = Path {
path: "std::option::Option".to_string(),
id: Id(42),
args: Some(Box::new(GenericArgs::AngleBracketed {
args: vec![GenericArg::Type(Type::Primitive("u32".to_string()))],
constraints: vec![],
})),
};
rkyv_roundtrip(&path);
// `FunctionPointer` is a `Box<FunctionPointer>` behind `omit_bounds` in `Type`.
// It transitively contains `Type` via `FunctionSignature`, exercising the cycle from the other direction.
let fp = Type::FunctionPointer(Box::new(FunctionPointer {
sig: FunctionSignature {
inputs: vec![("x".to_string(), Type::Primitive("i32".to_string()))],
output: Some(Type::Primitive("bool".to_string())),
is_c_variadic: false,
},
generic_params: vec![],
header: FunctionHeader {
is_const: false,
is_unsafe: false,
is_async: false,
abi: Abi::Rust,
},
}));
rkyv_roundtrip(&fp);
}
/// A helper function for roundtrip testing of rkyv-powered deserialization.
fn rkyv_roundtrip<T>(value: &T)
where
T: PartialEq
+ Debug
+ Archive
+ for<'a> rkyv::Serialize<
HighSerializer<AlignedVec, ArenaHandle<'a>, rkyv::rancor::Error>,
>,
T::Archived: rkyv::Deserialize<T, HighDeserializer<rkyv::rancor::Error>>
+ Debug
+ for<'a> CheckBytes<
Strategy<Validator<ArchiveValidator<'a>, SharedValidator>, rkyv::rancor::Error>,
>,
{
let bytes =
rkyv::api::high::to_bytes_in::<_, rkyv::rancor::Error>(value, AlignedVec::new())
.unwrap();
let archived = rkyv::api::high::access::<T::Archived, rkyv::rancor::Error>(&bytes)
.expect("Failed to access archived data");
let deserialized: T = rkyv::api::deserialize_using::<_, _, rkyv::rancor::Error>(
archived,
&mut rkyv::de::Pool::new(),
)
.unwrap();
assert_eq!(value, &deserialized);
}
}