1use {
2 crate::abi_digester::{AbiDigester, DigestError, DigestResult},
3 lazy_static::lazy_static,
4 log::*,
5 serde::Serialize,
6 std::any::type_name,
7};
8
9pub trait AbiExample: Sized {
10 fn example() -> Self;
11}
12
13macro_rules! tuple_example_impls {
19 ($(
20 $Tuple:ident {
21 $(($idx:tt) -> $T:ident)+
22 }
23 )+) => {
24 $(
25 impl<$($T:AbiExample),+> AbiExample for ($($T,)+) {
26 fn example() -> Self {
27 ($({ let x: $T = AbiExample::example(); x},)+)
28 }
29 }
30 )+
31 }
32}
33
34tuple_example_impls! {
36 Tuple1 {
37 (0) -> A
38 }
39 Tuple2 {
40 (0) -> A
41 (1) -> B
42 }
43 Tuple3 {
44 (0) -> A
45 (1) -> B
46 (2) -> C
47 }
48 Tuple4 {
49 (0) -> A
50 (1) -> B
51 (2) -> C
52 (3) -> D
53 }
54 Tuple5 {
55 (0) -> A
56 (1) -> B
57 (2) -> C
58 (3) -> D
59 (4) -> E
60 }
61 Tuple6 {
62 (0) -> A
63 (1) -> B
64 (2) -> C
65 (3) -> D
66 (4) -> E
67 (5) -> F
68 }
69 Tuple7 {
70 (0) -> A
71 (1) -> B
72 (2) -> C
73 (3) -> D
74 (4) -> E
75 (5) -> F
76 (6) -> G
77 }
78 Tuple8 {
79 (0) -> A
80 (1) -> B
81 (2) -> C
82 (3) -> D
83 (4) -> E
84 (5) -> F
85 (6) -> G
86 (7) -> H
87 }
88 Tuple9 {
89 (0) -> A
90 (1) -> B
91 (2) -> C
92 (3) -> D
93 (4) -> E
94 (5) -> F
95 (6) -> G
96 (7) -> H
97 (8) -> I
98 }
99 Tuple10 {
100 (0) -> A
101 (1) -> B
102 (2) -> C
103 (3) -> D
104 (4) -> E
105 (5) -> F
106 (6) -> G
107 (7) -> H
108 (8) -> I
109 (9) -> J
110 }
111 Tuple11 {
112 (0) -> A
113 (1) -> B
114 (2) -> C
115 (3) -> D
116 (4) -> E
117 (5) -> F
118 (6) -> G
119 (7) -> H
120 (8) -> I
121 (9) -> J
122 (10) -> K
123 }
124 Tuple12 {
125 (0) -> A
126 (1) -> B
127 (2) -> C
128 (3) -> D
129 (4) -> E
130 (5) -> F
131 (6) -> G
132 (7) -> H
133 (8) -> I
134 (9) -> J
135 (10) -> K
136 (11) -> L
137 }
138}
139
140macro_rules! array_example_impls {
142 {$n:expr, $t:ident $($ts:ident)*} => {
143 impl<T> AbiExample for [T; $n] where T: AbiExample {
144 fn example() -> Self {
145 [$t::example(), $($ts::example()),*]
146 }
147 }
148 array_example_impls!{($n - 1), $($ts)*}
149 };
150 {$n:expr,} => {
151 impl<T> AbiExample for [T; $n] {
152 fn example() -> Self { [] }
153 }
154 };
155}
156
157array_example_impls! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
158
159macro_rules! example_impls {
161 ($t:ty, $v:expr) => {
162 impl AbiExample for $t {
163 fn example() -> Self {
164 $v
165 }
166 }
167 };
168}
169
170example_impls! { (), () }
171example_impls! { bool, false }
172example_impls! { char, '\x00' }
173
174example_impls! { usize, 0 }
175example_impls! { u8, 0 }
176example_impls! { u16, 0 }
177example_impls! { u32, 0 }
178example_impls! { u64, 0 }
179example_impls! { u128, 0 }
180
181example_impls! { isize, 0 }
182example_impls! { i8, 0 }
183example_impls! { i16, 0 }
184example_impls! { i32, 0 }
185example_impls! { i64, 0 }
186example_impls! { i128, 0 }
187
188example_impls! { f32, 0.0f32 }
189example_impls! { f64, 0.0f64 }
190example_impls! { String, String::new() }
191example_impls! { std::time::Duration, std::time::Duration::from_secs(0) }
192example_impls! { std::sync::Once, std::sync::Once::new() }
193
194use std::sync::atomic::*;
195
196macro_rules! atomic_example_impls {
198 ($atomic_type: ident) => {
199 impl AbiExample for $atomic_type {
200 fn example() -> Self {
201 Self::new(AbiExample::example())
202 }
203 }
204 };
205}
206atomic_example_impls! { AtomicU8 }
207atomic_example_impls! { AtomicU16 }
208atomic_example_impls! { AtomicU32 }
209atomic_example_impls! { AtomicU64 }
210atomic_example_impls! { AtomicUsize }
211atomic_example_impls! { AtomicI8 }
212atomic_example_impls! { AtomicI16 }
213atomic_example_impls! { AtomicI32 }
214atomic_example_impls! { AtomicI64 }
215atomic_example_impls! { AtomicIsize }
216atomic_example_impls! { AtomicBool }
217
218#[cfg(not(target_os = "cbe"))]
219use generic_array::{ArrayLength, GenericArray};
220#[cfg(not(target_os = "cbe"))]
221impl<T: Default, U: ArrayLength<T>> AbiExample for GenericArray<T, U> {
222 fn example() -> Self {
223 Self::default()
224 }
225}
226
227use bv::{BitVec, BlockType};
228impl<T: BlockType> AbiExample for BitVec<T> {
229 fn example() -> Self {
230 Self::default()
231 }
232}
233
234impl<T: BlockType> IgnoreAsHelper for BitVec<T> {}
235impl<T: BlockType> EvenAsOpaque for BitVec<T> {}
236
237pub(crate) fn normalize_type_name(type_name: &str) -> String {
238 type_name.chars().filter(|c| *c != '&').collect()
239}
240
241type Placeholder = ();
242
243impl<T: Sized> AbiExample for T {
244 default fn example() -> Self {
245 <Placeholder>::type_erased_example()
246 }
247}
248
249trait TypeErasedExample<T> {
251 fn type_erased_example() -> T;
252}
253
254impl<T: Sized> TypeErasedExample<T> for Placeholder {
255 default fn type_erased_example() -> T {
256 panic!(
257 "derive or implement AbiExample/AbiEnumVisitor for {}",
258 type_name::<T>()
259 );
260 }
261}
262
263impl<T: Default + Serialize> TypeErasedExample<T> for Placeholder {
264 default fn type_erased_example() -> T {
265 let original_type_name = type_name::<T>();
266 let normalized_type_name = normalize_type_name(original_type_name);
267
268 if normalized_type_name.starts_with("cbe") {
269 panic!("derive or implement AbiExample/AbiEnumVisitor for {original_type_name}");
270 } else {
271 panic!("new unrecognized type for ABI digest!: {original_type_name}")
272 }
273 }
274}
275
276impl<T: AbiExample> AbiExample for Option<T> {
277 fn example() -> Self {
278 info!("AbiExample for (Option<T>): {}", type_name::<Self>());
279 Some(T::example())
280 }
281}
282
283impl<O: AbiExample, E: AbiExample> AbiExample for Result<O, E> {
284 fn example() -> Self {
285 info!("AbiExample for (Result<O, E>): {}", type_name::<Self>());
286 Ok(O::example())
287 }
288}
289
290impl<T: AbiExample> AbiExample for Box<T> {
291 fn example() -> Self {
292 info!("AbiExample for (Box<T>): {}", type_name::<Self>());
293 Box::new(T::example())
294 }
295}
296
297impl<T> AbiExample for Box<dyn Fn(&mut T) + Sync + Send> {
298 fn example() -> Self {
299 info!("AbiExample for (Box<T>): {}", type_name::<Self>());
300 Box::new(move |_t: &mut T| {})
301 }
302}
303
304impl<T, U> AbiExample for Box<dyn Fn(&mut T, U) + Sync + Send> {
305 fn example() -> Self {
306 info!("AbiExample for (Box<T, U>): {}", type_name::<Self>());
307 Box::new(move |_t: &mut T, _u: U| {})
308 }
309}
310
311impl<T: AbiExample> AbiExample for Box<[T]> {
312 fn example() -> Self {
313 info!("AbiExample for (Box<[T]>): {}", type_name::<Self>());
314 Box::new([T::example()])
315 }
316}
317
318impl<T: AbiExample> AbiExample for std::marker::PhantomData<T> {
319 fn example() -> Self {
320 info!("AbiExample for (PhantomData<T>): {}", type_name::<Self>());
321 <std::marker::PhantomData<T>>::default()
322 }
323}
324
325impl<T: AbiExample> AbiExample for std::sync::Arc<T> {
326 fn example() -> Self {
327 info!("AbiExample for (Arc<T>): {}", type_name::<Self>());
328 std::sync::Arc::new(T::example())
329 }
330}
331
332impl<T: AbiExample> AbiExample for std::rc::Rc<T> {
333 fn example() -> Self {
334 info!("AbiExample for (Rc<T>): {}", type_name::<Self>());
335 std::rc::Rc::new(T::example())
336 }
337}
338
339impl<T: AbiExample> AbiExample for std::sync::Mutex<T> {
340 fn example() -> Self {
341 info!("AbiExample for (Mutex<T>): {}", type_name::<Self>());
342 std::sync::Mutex::new(T::example())
343 }
344}
345
346impl<T: AbiExample> AbiExample for std::sync::RwLock<T> {
347 fn example() -> Self {
348 info!("AbiExample for (RwLock<T>): {}", type_name::<Self>());
349 std::sync::RwLock::new(T::example())
350 }
351}
352
353use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
354
355impl<
356 T: std::cmp::Eq + std::hash::Hash + AbiExample,
357 S: AbiExample,
358 H: std::hash::BuildHasher + Default,
359 > AbiExample for HashMap<T, S, H>
360{
361 fn example() -> Self {
362 info!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
363 let mut map = HashMap::default();
364 map.insert(T::example(), S::example());
365 map
366 }
367}
368
369#[cfg(not(target_os = "cbe"))]
370impl<
371 T: Clone + std::cmp::Eq + std::hash::Hash + AbiExample,
372 S: Clone + AbiExample,
373 H: std::hash::BuildHasher + Default,
374 > AbiExample for im::HashMap<T, S, H>
375{
376 fn example() -> Self {
377 info!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
378 let mut map = im::HashMap::default();
379 map.insert(T::example(), S::example());
380 map
381 }
382}
383
384impl<T: std::cmp::Ord + AbiExample, S: AbiExample> AbiExample for BTreeMap<T, S> {
385 fn example() -> Self {
386 info!("AbiExample for (BTreeMap<T, S>): {}", type_name::<Self>());
387 let mut map = BTreeMap::default();
388 map.insert(T::example(), S::example());
389 map
390 }
391}
392
393impl<T: AbiExample> AbiExample for Vec<T> {
394 fn example() -> Self {
395 info!("AbiExample for (Vec<T>): {}", type_name::<Self>());
396 vec![T::example()]
397 }
398}
399
400lazy_static! {
401 static ref VEC_U8: Vec<u8> = vec![u8::default()];
403}
404
405impl AbiExample for &Vec<u8> {
406 fn example() -> Self {
407 info!("AbiExample for (&Vec<u8>): {}", type_name::<Self>());
408 &VEC_U8
409 }
410}
411
412impl AbiExample for &[u8] {
413 fn example() -> Self {
414 info!("AbiExample for (&[u8]): {}", type_name::<Self>());
415 &VEC_U8[..]
416 }
417}
418
419impl<T: AbiExample> AbiExample for VecDeque<T> {
420 fn example() -> Self {
421 info!("AbiExample for (Vec<T>): {}", type_name::<Self>());
422 VecDeque::from(vec![T::example()])
423 }
424}
425
426impl<T: std::cmp::Eq + std::hash::Hash + AbiExample, H: std::hash::BuildHasher + Default> AbiExample
427 for HashSet<T, H>
428{
429 fn example() -> Self {
430 info!("AbiExample for (HashSet<T, H>): {}", type_name::<Self>());
431 let mut set: HashSet<T, H> = HashSet::default();
432 set.insert(T::example());
433 set
434 }
435}
436
437impl<T: std::cmp::Ord + AbiExample> AbiExample for BTreeSet<T> {
438 fn example() -> Self {
439 info!("AbiExample for (BTreeSet<T>): {}", type_name::<Self>());
440 let mut set: BTreeSet<T> = BTreeSet::default();
441 set.insert(T::example());
442 set
443 }
444}
445
446#[cfg(not(target_os = "cbe"))]
447impl AbiExample for memmap2::MmapMut {
448 fn example() -> Self {
449 memmap2::MmapMut::map_anon(1).expect("failed to map the data file")
450 }
451}
452
453#[cfg(not(target_os = "cbe"))]
454impl AbiExample for std::path::PathBuf {
455 fn example() -> Self {
456 std::path::PathBuf::from(String::example())
457 }
458}
459
460use std::net::{IpAddr, Ipv4Addr, SocketAddr};
461impl AbiExample for SocketAddr {
462 fn example() -> Self {
463 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0)
464 }
465}
466
467pub trait AbiEnumVisitor: Serialize {
469 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult;
470}
471
472pub trait IgnoreAsHelper {}
473pub trait EvenAsOpaque {}
474
475impl<T: Serialize + ?Sized> AbiEnumVisitor for T {
476 default fn visit_for_abi(&self, _digester: &mut AbiDigester) -> DigestResult {
477 unreachable!(
478 "AbiEnumVisitor must be implemented for {}",
479 type_name::<T>()
480 );
481 }
482}
483
484impl<T: Serialize + ?Sized + AbiExample> AbiEnumVisitor for T {
485 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
486 info!("AbiEnumVisitor for (default): {}", type_name::<T>());
487 T::example()
488 .serialize(digester.create_new())
489 .map_err(DigestError::wrap_by_type::<T>)
490 }
491}
492
493impl<T: Serialize + ?Sized + AbiEnumVisitor> AbiEnumVisitor for &T {
497 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
498 info!("AbiEnumVisitor for (&default): {}", type_name::<T>());
499 T::visit_for_abi(self, digester)
501 }
502}
503
504impl<T: Serialize + IgnoreAsHelper> AbiEnumVisitor for &T {
507 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
508 info!("AbiEnumVisitor for (IgnoreAsHelper): {}", type_name::<T>());
509 self.serialize(digester.create_new())
510 .map_err(DigestError::wrap_by_type::<T>)
511 }
512}
513
514impl<T: Serialize + IgnoreAsHelper + EvenAsOpaque> AbiEnumVisitor for &T {
517 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
518 info!("AbiEnumVisitor for (IgnoreAsOpaque): {}", type_name::<T>());
519 let top_scope = type_name::<T>().split("::").next().unwrap();
520 self.serialize(digester.create_new_opaque(top_scope))
521 .map_err(DigestError::wrap_by_type::<T>)
522 }
523}
524
525impl<T: AbiEnumVisitor> AbiEnumVisitor for Option<T> {
528 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
529 info!("AbiEnumVisitor for (Option<T>): {}", type_name::<Self>());
530
531 let variant: Self = Option::Some(T::example());
532 variant.serialize(digester.create_new())
535 }
536}
537
538impl<O: AbiEnumVisitor, E: AbiEnumVisitor> AbiEnumVisitor for Result<O, E> {
539 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
540 info!("AbiEnumVisitor for (Result<O, E>): {}", type_name::<Self>());
541
542 digester.update(&["enum Result (variants = 2)"]);
543 let variant: Self = Result::Ok(O::example());
544 variant.serialize(digester.create_enum_child()?)?;
545
546 let variant: Self = Result::Err(E::example());
547 variant.serialize(digester.create_enum_child()?)?;
548
549 digester.create_child()
550 }
551}
552
553impl<T: AbiExample> AbiExample for once_cell::sync::OnceCell<T> {
554 fn example() -> Self {
555 Self::with_value(T::example())
556 }
557}