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 = "solana"))]
219use generic_array::{ArrayLength, GenericArray};
220#[cfg(not(target_os = "solana"))]
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("solana") {
269 panic!(
270 "derive or implement AbiExample/AbiEnumVisitor for {}",
271 original_type_name
272 );
273 } else {
274 panic!(
275 "new unrecognized type for ABI digest!: {}",
276 original_type_name
277 )
278 }
279 }
280}
281
282impl<T: AbiExample> AbiExample for Option<T> {
283 fn example() -> Self {
284 info!("AbiExample for (Option<T>): {}", type_name::<Self>());
285 Some(T::example())
286 }
287}
288
289impl<O: AbiExample, E: AbiExample> AbiExample for Result<O, E> {
290 fn example() -> Self {
291 info!("AbiExample for (Result<O, E>): {}", type_name::<Self>());
292 Ok(O::example())
293 }
294}
295
296impl<T: AbiExample> AbiExample for Box<T> {
297 fn example() -> Self {
298 info!("AbiExample for (Box<T>): {}", type_name::<Self>());
299 Box::new(T::example())
300 }
301}
302
303impl<T> AbiExample for Box<dyn Fn(&mut T) + Sync + Send> {
304 fn example() -> Self {
305 info!("AbiExample for (Box<T>): {}", type_name::<Self>());
306 Box::new(move |_t: &mut T| {})
307 }
308}
309
310impl<T, U> AbiExample for Box<dyn Fn(&mut T, U) + Sync + Send> {
311 fn example() -> Self {
312 info!("AbiExample for (Box<T, U>): {}", type_name::<Self>());
313 Box::new(move |_t: &mut T, _u: U| {})
314 }
315}
316
317impl<T: AbiExample> AbiExample for Box<[T]> {
318 fn example() -> Self {
319 info!("AbiExample for (Box<[T]>): {}", type_name::<Self>());
320 Box::new([T::example()])
321 }
322}
323
324impl<T: AbiExample> AbiExample for std::marker::PhantomData<T> {
325 fn example() -> Self {
326 info!("AbiExample for (PhantomData<T>): {}", type_name::<Self>());
327 <std::marker::PhantomData<T>>::default()
328 }
329}
330
331impl<T: AbiExample> AbiExample for std::sync::Arc<T> {
332 fn example() -> Self {
333 info!("AbiExample for (Arc<T>): {}", type_name::<Self>());
334 std::sync::Arc::new(T::example())
335 }
336}
337
338impl<T: AbiExample> AbiExample for std::rc::Rc<T> {
339 fn example() -> Self {
340 info!("AbiExample for (Rc<T>): {}", type_name::<Self>());
341 std::rc::Rc::new(T::example())
342 }
343}
344
345impl<T: AbiExample> AbiExample for std::sync::Mutex<T> {
346 fn example() -> Self {
347 info!("AbiExample for (Mutex<T>): {}", type_name::<Self>());
348 std::sync::Mutex::new(T::example())
349 }
350}
351
352impl<T: AbiExample> AbiExample for std::sync::RwLock<T> {
353 fn example() -> Self {
354 info!("AbiExample for (RwLock<T>): {}", type_name::<Self>());
355 std::sync::RwLock::new(T::example())
356 }
357}
358
359use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
360
361impl<
362 T: std::cmp::Eq + std::hash::Hash + AbiExample,
363 S: AbiExample,
364 H: std::hash::BuildHasher + Default,
365 > AbiExample for HashMap<T, S, H>
366{
367 fn example() -> Self {
368 info!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
369 let mut map = HashMap::default();
370 map.insert(T::example(), S::example());
371 map
372 }
373}
374
375#[cfg(not(target_os = "solana"))]
376impl<
377 T: Clone + std::cmp::Eq + std::hash::Hash + AbiExample,
378 S: Clone + AbiExample,
379 H: std::hash::BuildHasher + Default,
380 > AbiExample for im::HashMap<T, S, H>
381{
382 fn example() -> Self {
383 info!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
384 let mut map = im::HashMap::default();
385 map.insert(T::example(), S::example());
386 map
387 }
388}
389
390impl<T: std::cmp::Ord + AbiExample, S: AbiExample> AbiExample for BTreeMap<T, S> {
391 fn example() -> Self {
392 info!("AbiExample for (BTreeMap<T, S>): {}", type_name::<Self>());
393 let mut map = BTreeMap::default();
394 map.insert(T::example(), S::example());
395 map
396 }
397}
398
399impl<T: AbiExample> AbiExample for Vec<T> {
400 fn example() -> Self {
401 info!("AbiExample for (Vec<T>): {}", type_name::<Self>());
402 vec![T::example()]
403 }
404}
405
406lazy_static! {
407 static ref VEC_U8: Vec<u8> = vec![u8::default()];
409}
410
411impl AbiExample for &Vec<u8> {
412 fn example() -> Self {
413 info!("AbiExample for (&Vec<u8>): {}", type_name::<Self>());
414 &*VEC_U8
415 }
416}
417
418impl AbiExample for &[u8] {
419 fn example() -> Self {
420 info!("AbiExample for (&[u8]): {}", type_name::<Self>());
421 &VEC_U8[..]
422 }
423}
424
425impl<T: AbiExample> AbiExample for VecDeque<T> {
426 fn example() -> Self {
427 info!("AbiExample for (Vec<T>): {}", type_name::<Self>());
428 VecDeque::from(vec![T::example()])
429 }
430}
431
432impl<T: std::cmp::Eq + std::hash::Hash + AbiExample, H: std::hash::BuildHasher + Default> AbiExample
433 for HashSet<T, H>
434{
435 fn example() -> Self {
436 info!("AbiExample for (HashSet<T, H>): {}", type_name::<Self>());
437 let mut set: HashSet<T, H> = HashSet::default();
438 set.insert(T::example());
439 set
440 }
441}
442
443impl<T: std::cmp::Ord + AbiExample> AbiExample for BTreeSet<T> {
444 fn example() -> Self {
445 info!("AbiExample for (BTreeSet<T>): {}", type_name::<Self>());
446 let mut set: BTreeSet<T> = BTreeSet::default();
447 set.insert(T::example());
448 set
449 }
450}
451
452#[cfg(not(target_os = "solana"))]
453impl AbiExample for memmap2::MmapMut {
454 fn example() -> Self {
455 memmap2::MmapMut::map_anon(1).expect("failed to map the data file")
456 }
457}
458
459#[cfg(not(target_os = "solana"))]
460impl AbiExample for std::path::PathBuf {
461 fn example() -> Self {
462 std::path::PathBuf::from(String::example())
463 }
464}
465
466use std::net::{IpAddr, Ipv4Addr, SocketAddr};
467impl AbiExample for SocketAddr {
468 fn example() -> Self {
469 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0)
470 }
471}
472
473pub trait AbiEnumVisitor: Serialize {
475 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult;
476}
477
478pub trait IgnoreAsHelper {}
479pub trait EvenAsOpaque {}
480
481impl<T: Serialize + ?Sized> AbiEnumVisitor for T {
482 default fn visit_for_abi(&self, _digester: &mut AbiDigester) -> DigestResult {
483 unreachable!(
484 "AbiEnumVisitor must be implemented for {}",
485 type_name::<T>()
486 );
487 }
488}
489
490impl<T: Serialize + ?Sized + AbiExample> AbiEnumVisitor for T {
491 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
492 info!("AbiEnumVisitor for (default): {}", type_name::<T>());
493 T::example()
494 .serialize(digester.create_new())
495 .map_err(DigestError::wrap_by_type::<T>)
496 }
497}
498
499impl<T: Serialize + ?Sized + AbiEnumVisitor> AbiEnumVisitor for &T {
503 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
504 info!("AbiEnumVisitor for (&default): {}", type_name::<T>());
505 T::visit_for_abi(self, digester)
507 }
508}
509
510impl<T: Serialize + IgnoreAsHelper> AbiEnumVisitor for &T {
513 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
514 info!("AbiEnumVisitor for (IgnoreAsHelper): {}", type_name::<T>());
515 self.serialize(digester.create_new())
516 .map_err(DigestError::wrap_by_type::<T>)
517 }
518}
519
520impl<T: Serialize + IgnoreAsHelper + EvenAsOpaque> AbiEnumVisitor for &T {
523 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
524 info!("AbiEnumVisitor for (IgnoreAsOpaque): {}", type_name::<T>());
525 let top_scope = type_name::<T>().split("::").next().unwrap();
526 self.serialize(digester.create_new_opaque(top_scope))
527 .map_err(DigestError::wrap_by_type::<T>)
528 }
529}
530
531impl<T: AbiEnumVisitor> AbiEnumVisitor for Option<T> {
534 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
535 info!("AbiEnumVisitor for (Option<T>): {}", type_name::<Self>());
536
537 let variant: Self = Option::Some(T::example());
538 variant.serialize(digester.create_new())
541 }
542}
543
544impl<O: AbiEnumVisitor, E: AbiEnumVisitor> AbiEnumVisitor for Result<O, E> {
545 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
546 info!("AbiEnumVisitor for (Result<O, E>): {}", type_name::<Self>());
547
548 digester.update(&["enum Result (variants = 2)"]);
549 let variant: Self = Result::Ok(O::example());
550 variant.serialize(digester.create_enum_child()?)?;
551
552 let variant: Self = Result::Err(E::example());
553 variant.serialize(digester.create_enum_child()?)?;
554
555 digester.create_child()
556 }
557}
558
559impl<T: AbiExample> AbiExample for once_cell::sync::OnceCell<T> {
560 fn example() -> Self {
561 Self::with_value(T::example())
562 }
563}