1use {
2 crate::abi_digester::{AbiDigester, DigestError, DigestResult},
3 serde::Serialize,
4 std::any::type_name,
5};
6
7pub trait AbiExample: Sized {
26 fn example() -> Self;
27}
28
29macro_rules! tuple_example_impls {
35 ($(
36 $Tuple:ident {
37 $(($idx:tt) -> $T:ident)+
38 }
39 )+) => {
40 $(
41 impl<$($T:AbiExample),+> AbiExample for ($($T,)+) {
42 fn example() -> Self {
43 ($({ let x: $T = AbiExample::example(); x},)+)
44 }
45 }
46 )+
47 }
48}
49
50tuple_example_impls! {
52 Tuple1 {
53 (0) -> A
54 }
55 Tuple2 {
56 (0) -> A
57 (1) -> B
58 }
59 Tuple3 {
60 (0) -> A
61 (1) -> B
62 (2) -> C
63 }
64 Tuple4 {
65 (0) -> A
66 (1) -> B
67 (2) -> C
68 (3) -> D
69 }
70 Tuple5 {
71 (0) -> A
72 (1) -> B
73 (2) -> C
74 (3) -> D
75 (4) -> E
76 }
77 Tuple6 {
78 (0) -> A
79 (1) -> B
80 (2) -> C
81 (3) -> D
82 (4) -> E
83 (5) -> F
84 }
85 Tuple7 {
86 (0) -> A
87 (1) -> B
88 (2) -> C
89 (3) -> D
90 (4) -> E
91 (5) -> F
92 (6) -> G
93 }
94 Tuple8 {
95 (0) -> A
96 (1) -> B
97 (2) -> C
98 (3) -> D
99 (4) -> E
100 (5) -> F
101 (6) -> G
102 (7) -> H
103 }
104 Tuple9 {
105 (0) -> A
106 (1) -> B
107 (2) -> C
108 (3) -> D
109 (4) -> E
110 (5) -> F
111 (6) -> G
112 (7) -> H
113 (8) -> I
114 }
115 Tuple10 {
116 (0) -> A
117 (1) -> B
118 (2) -> C
119 (3) -> D
120 (4) -> E
121 (5) -> F
122 (6) -> G
123 (7) -> H
124 (8) -> I
125 (9) -> J
126 }
127 Tuple11 {
128 (0) -> A
129 (1) -> B
130 (2) -> C
131 (3) -> D
132 (4) -> E
133 (5) -> F
134 (6) -> G
135 (7) -> H
136 (8) -> I
137 (9) -> J
138 (10) -> K
139 }
140 Tuple12 {
141 (0) -> A
142 (1) -> B
143 (2) -> C
144 (3) -> D
145 (4) -> E
146 (5) -> F
147 (6) -> G
148 (7) -> H
149 (8) -> I
150 (9) -> J
151 (10) -> K
152 (11) -> L
153 }
154}
155
156impl<const N: usize, T: AbiExample> AbiExample for [T; N] {
157 fn example() -> Self {
158 std::array::from_fn(|_| T::example())
159 }
160}
161
162macro_rules! example_impls {
164 ($t:ty, $v:expr) => {
165 impl AbiExample for $t {
166 fn example() -> Self {
167 $v
168 }
169 }
170 };
171}
172
173example_impls! { (), () }
174example_impls! { bool, false }
175example_impls! { char, '\x00' }
176
177example_impls! { usize, 0 }
178example_impls! { u8, 0 }
179example_impls! { u16, 0 }
180example_impls! { u32, 0 }
181example_impls! { u64, 0 }
182example_impls! { u128, 0 }
183
184example_impls! { isize, 0 }
185example_impls! { i8, 0 }
186example_impls! { i16, 0 }
187example_impls! { i32, 0 }
188example_impls! { i64, 0 }
189example_impls! { i128, 0 }
190
191example_impls! { f32, 0.0f32 }
192example_impls! { f64, 0.0f64 }
193example_impls! { String, String::new() }
194example_impls! { std::time::Duration, std::time::Duration::from_secs(0) }
195example_impls! { std::sync::Once, std::sync::Once::new() }
196
197example_impls! { bytes::Bytes, bytes::Bytes::new() }
198
199use std::sync::atomic::*;
200
201macro_rules! atomic_example_impls {
203 ($atomic_type: ident) => {
204 impl AbiExample for $atomic_type {
205 fn example() -> Self {
206 Self::new(AbiExample::example())
207 }
208 }
209 };
210}
211atomic_example_impls! { AtomicU8 }
212atomic_example_impls! { AtomicU16 }
213atomic_example_impls! { AtomicU32 }
214atomic_example_impls! { AtomicU64 }
215atomic_example_impls! { AtomicUsize }
216atomic_example_impls! { AtomicI8 }
217atomic_example_impls! { AtomicI16 }
218atomic_example_impls! { AtomicI32 }
219atomic_example_impls! { AtomicI64 }
220atomic_example_impls! { AtomicIsize }
221atomic_example_impls! { AtomicBool }
222
223use bv::{BitVec, BlockType};
224impl<T: BlockType> AbiExample for BitVec<T> {
225 fn example() -> Self {
226 Self::default()
227 }
228}
229
230impl<T: BlockType> TransparentAsHelper for BitVec<T> {}
231impl<T: BlockType> EvenAsOpaque for BitVec<T> {
237 const TYPE_NAME_MATCHER: &'static str = "bv::bit_vec::inner::";
238}
239
240use serde_with::ser::SerializeAsWrap;
241impl<T: ?Sized, U: ?Sized> TransparentAsHelper for SerializeAsWrap<'_, T, U> {}
242impl<T: ?Sized, U: ?Sized> EvenAsOpaque for SerializeAsWrap<'_, T, U> {
245 const TYPE_NAME_MATCHER: &'static str = "serde_with::ser::SerializeAsWrap<";
246}
247
248pub(crate) fn normalize_type_name(type_name: &str) -> String {
249 type_name.chars().filter(|c| *c != '&').collect()
250}
251
252type Placeholder = ();
253
254impl<T: Sized> AbiExample for T {
255 default fn example() -> Self {
256 <Placeholder>::type_erased_example()
257 }
258}
259
260trait TypeErasedExample<T> {
262 fn type_erased_example() -> T;
263}
264
265impl<T: Sized> TypeErasedExample<T> for Placeholder {
266 default fn type_erased_example() -> T {
267 panic!(
268 "derive or implement AbiExample/AbiEnumVisitor for {}",
269 type_name::<T>()
270 );
271 }
272}
273
274impl<T: Default + Serialize> TypeErasedExample<T> for Placeholder {
275 default fn type_erased_example() -> T {
276 let original_type_name = type_name::<T>();
277 let normalized_type_name = normalize_type_name(original_type_name);
278
279 if normalized_type_name.starts_with("solana") {
280 panic!("derive or implement AbiExample/AbiEnumVisitor for {original_type_name}");
281 } else {
282 panic!("new unrecognized type for ABI digest!: {original_type_name}")
283 }
284 }
285}
286
287impl<T: AbiExample> AbiExample for Option<T> {
288 fn example() -> Self {
289 println!("AbiExample for (Option<T>): {}", type_name::<Self>());
290 Some(T::example())
291 }
292}
293
294impl<O: AbiExample, E: AbiExample> AbiExample for Result<O, E> {
295 fn example() -> Self {
296 println!("AbiExample for (Result<O, E>): {}", type_name::<Self>());
297 Ok(O::example())
298 }
299}
300
301impl<T: AbiExample> AbiExample for Box<T> {
302 fn example() -> Self {
303 println!("AbiExample for (Box<T>): {}", type_name::<Self>());
304 Box::new(T::example())
305 }
306}
307
308impl<T> AbiExample for Box<dyn Fn(&mut T) + Sync + Send> {
309 fn example() -> Self {
310 println!("AbiExample for (Box<T>): {}", type_name::<Self>());
311 Box::new(move |_t: &mut T| {})
312 }
313}
314
315impl<T, U> AbiExample for Box<dyn Fn(&mut T, U) + Sync + Send> {
316 fn example() -> Self {
317 println!("AbiExample for (Box<T, U>): {}", type_name::<Self>());
318 Box::new(move |_t: &mut T, _u: U| {})
319 }
320}
321
322impl<T: AbiExample> AbiExample for Box<[T]> {
323 fn example() -> Self {
324 println!("AbiExample for (Box<[T]>): {}", type_name::<Self>());
325 Box::new([T::example()])
326 }
327}
328
329impl<T: AbiExample> AbiExample for std::marker::PhantomData<T> {
330 fn example() -> Self {
331 println!("AbiExample for (PhantomData<T>): {}", type_name::<Self>());
332 std::marker::PhantomData::<T>
333 }
334}
335
336impl<T: AbiExample> AbiExample for std::sync::Arc<T> {
337 fn example() -> Self {
338 println!("AbiExample for (Arc<T>): {}", type_name::<Self>());
339 std::sync::Arc::new(T::example())
340 }
341}
342
343fn leak_and_inhibit_drop<'a, T>(t: T) -> &'a mut T {
349 Box::leak(Box::new(t))
350}
351
352impl<T: AbiExample> AbiExample for &T {
353 fn example() -> Self {
354 println!("AbiExample for (&T): {}", type_name::<Self>());
355 leak_and_inhibit_drop(T::example())
356 }
357}
358
359impl<T: AbiExample> AbiExample for &[T] {
360 fn example() -> Self {
361 println!("AbiExample for (&[T]): {}", type_name::<Self>());
362 leak_and_inhibit_drop(vec![T::example()])
363 }
364}
365
366impl<T: AbiExample> AbiExample for std::sync::Weak<T> {
367 fn example() -> Self {
368 println!("AbiExample for (Arc's Weak<T>): {}", type_name::<Self>());
369 std::sync::Arc::downgrade(leak_and_inhibit_drop(std::sync::Arc::new(T::example())))
371 }
372}
373
374impl<T: AbiExample> AbiExample for std::rc::Rc<T> {
375 fn example() -> Self {
376 println!("AbiExample for (Rc<T>): {}", type_name::<Self>());
377 std::rc::Rc::new(T::example())
378 }
379}
380
381impl<T: AbiExample> AbiExample for std::rc::Weak<T> {
382 fn example() -> Self {
383 println!("AbiExample for (Rc's Weak<T>): {}", type_name::<Self>());
384 std::rc::Rc::downgrade(leak_and_inhibit_drop(std::rc::Rc::new(T::example())))
386 }
387}
388
389impl<T: AbiExample> AbiExample for std::sync::Mutex<T> {
390 fn example() -> Self {
391 println!("AbiExample for (Mutex<T>): {}", type_name::<Self>());
392 std::sync::Mutex::new(T::example())
393 }
394}
395
396impl<T: AbiExample> AbiExample for std::sync::RwLock<T> {
397 fn example() -> Self {
398 println!("AbiExample for (RwLock<T>): {}", type_name::<Self>());
399 std::sync::RwLock::new(T::example())
400 }
401}
402
403use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
404
405impl<
406 T: std::cmp::Eq + std::hash::Hash + AbiExample,
407 S: AbiExample,
408 H: std::hash::BuildHasher + Default,
409 > AbiExample for HashMap<T, S, H>
410{
411 fn example() -> Self {
412 println!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
413 let mut map = HashMap::default();
414 map.insert(T::example(), S::example());
415 map
416 }
417}
418
419#[cfg(not(target_os = "solana"))]
420impl<
421 T: Clone + std::cmp::Eq + std::hash::Hash + AbiExample,
422 S: Clone + AbiExample,
423 H: std::hash::BuildHasher + Default,
424 > AbiExample for im::HashMap<T, S, H>
425{
426 fn example() -> Self {
427 println!("AbiExample for (HashMap<T, S, H>): {}", type_name::<Self>());
428 let mut map = im::HashMap::default();
429 map.insert(T::example(), S::example());
430 map
431 }
432}
433
434impl<T: std::cmp::Ord + AbiExample, S: AbiExample> AbiExample for BTreeMap<T, S> {
435 fn example() -> Self {
436 println!("AbiExample for (BTreeMap<T, S>): {}", type_name::<Self>());
437 let mut map = BTreeMap::default();
438 map.insert(T::example(), S::example());
439 map
440 }
441}
442
443impl<T: AbiExample> AbiExample for Vec<T> {
444 fn example() -> Self {
445 println!("AbiExample for (Vec<T>): {}", type_name::<Self>());
446 vec![T::example()]
447 }
448}
449
450impl<T: AbiExample> AbiExample for VecDeque<T> {
451 fn example() -> Self {
452 println!("AbiExample for (Vec<T>): {}", type_name::<Self>());
453 VecDeque::from(vec![T::example()])
454 }
455}
456
457impl<T: std::cmp::Eq + std::hash::Hash + AbiExample, H: std::hash::BuildHasher + Default> AbiExample
458 for HashSet<T, H>
459{
460 fn example() -> Self {
461 println!("AbiExample for (HashSet<T, H>): {}", type_name::<Self>());
462 let mut set: HashSet<T, H> = HashSet::default();
463 set.insert(T::example());
464 set
465 }
466}
467
468impl<T: std::cmp::Ord + AbiExample> AbiExample for BTreeSet<T> {
469 fn example() -> Self {
470 println!("AbiExample for (BTreeSet<T>): {}", type_name::<Self>());
471 let mut set: BTreeSet<T> = BTreeSet::default();
472 set.insert(T::example());
473 set
474 }
475}
476
477#[cfg(not(target_os = "solana"))]
478impl AbiExample for memmap2::MmapMut {
479 fn example() -> Self {
480 memmap2::MmapMut::map_anon(1).expect("failed to map the data file")
481 }
482}
483
484#[cfg(not(target_os = "solana"))]
485impl AbiExample for std::path::PathBuf {
486 fn example() -> Self {
487 std::path::PathBuf::from(String::example())
488 }
489}
490
491#[cfg(not(target_os = "solana"))]
492impl AbiExample for std::time::SystemTime {
493 fn example() -> Self {
494 std::time::SystemTime::UNIX_EPOCH
495 }
496}
497
498use std::net::{IpAddr, Ipv4Addr, SocketAddr};
499impl AbiExample for SocketAddr {
500 fn example() -> Self {
501 SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0)
502 }
503}
504
505impl AbiExample for IpAddr {
506 fn example() -> Self {
507 IpAddr::V4(Ipv4Addr::UNSPECIFIED)
508 }
509}
510
511pub trait AbiEnumVisitor: Serialize {
520 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult;
521}
522
523pub trait TransparentAsHelper {}
524pub trait EvenAsOpaque {
525 const TYPE_NAME_MATCHER: &'static str;
526}
527
528impl<T: Serialize + ?Sized> AbiEnumVisitor for T {
529 default fn visit_for_abi(&self, _digester: &mut AbiDigester) -> DigestResult {
530 unreachable!(
531 "AbiEnumVisitor must be implemented for {}",
532 type_name::<T>()
533 );
534 }
535}
536
537impl<T: Serialize + AbiExample> AbiEnumVisitor for T {
538 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
539 println!("AbiEnumVisitor for T: {}", type_name::<T>());
540 T::example()
543 .serialize(digester.create_new())
544 .map_err(DigestError::wrap_by_type::<T>)
545 }
546}
547
548impl<T: Serialize + ?Sized + AbiEnumVisitor> AbiEnumVisitor for &T {
552 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
553 println!("AbiEnumVisitor for &T: {}", type_name::<T>());
554 T::visit_for_abi(self, digester)
556 }
557}
558
559impl<T: Serialize + TransparentAsHelper> AbiEnumVisitor for &T {
562 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
563 println!(
564 "AbiEnumVisitor for (TransparentAsHelper): {}",
565 type_name::<T>()
566 );
567 self.serialize(digester.create_new())
568 .map_err(DigestError::wrap_by_type::<T>)
569 }
570}
571
572impl<T: Serialize + TransparentAsHelper + EvenAsOpaque> AbiEnumVisitor for &T {
575 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
576 let type_name = type_name::<T>();
577 let matcher = T::TYPE_NAME_MATCHER;
578 println!("AbiEnumVisitor for (EvenAsOpaque): {type_name}: matcher: {matcher}");
579 self.serialize(digester.create_new_opaque(matcher))
580 .map_err(DigestError::wrap_by_type::<T>)
581 }
582}
583
584impl<T: AbiEnumVisitor> AbiEnumVisitor for Option<T> {
587 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
588 println!("AbiEnumVisitor for (Option<T>): {}", type_name::<Self>());
589
590 let variant: Self = Option::Some(T::example());
591 variant.serialize(digester.create_new())
594 }
595}
596
597impl<O: AbiEnumVisitor, E: AbiEnumVisitor> AbiEnumVisitor for Result<O, E> {
598 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
599 println!("AbiEnumVisitor for (Result<O, E>): {}", type_name::<Self>());
600
601 digester.update(&["enum Result (variants = 2)"]);
602 let variant: Self = Result::Ok(O::example());
603 variant.serialize(digester.create_enum_child()?)?;
604
605 let variant: Self = Result::Err(E::example());
606 variant.serialize(digester.create_enum_child()?)?;
607
608 digester.create_child()
609 }
610}
611
612#[cfg(not(target_os = "solana"))]
613impl<T: AbiExample> AbiExample for std::sync::OnceLock<T> {
614 fn example() -> Self {
615 Self::from(T::example())
616 }
617}
618
619#[cfg(not(target_os = "solana"))]
620impl<
621 T: std::cmp::Eq + std::hash::Hash + AbiExample,
622 S: AbiExample,
623 H: std::hash::BuildHasher + Default + std::clone::Clone,
624 > AbiExample for dashmap::DashMap<T, S, H>
625{
626 fn example() -> Self {
627 println!("AbiExample for (DashMap<T, S, H>): {}", type_name::<Self>());
628 let map = dashmap::DashMap::default();
629 map.insert(T::example(), S::example());
630 map
631 }
632}
633
634#[cfg(not(target_os = "solana"))]
635impl<T: AbiExample> AbiExample for boxcar::Vec<T> {
636 fn example() -> Self {
637 println!("AbiExample for (boxcar::Vec): {}", type_name::<Self>());
638 let vec = boxcar::Vec::new();
639 vec.push(T::example());
640 vec
641 }
642}