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
434#[cfg(not(target_os = "solana"))]
435impl<K, V, S, P> AbiExample for imbl::GenericHashMap<K, V, S, P>
436where
437 K: Clone + Eq + std::hash::Hash + AbiExample,
438 V: Clone + AbiExample,
439 S: Clone + std::hash::BuildHasher + Default,
440 P: imbl::shared_ptr::SharedPointerKind,
441{
442 fn example() -> Self {
443 let mut map = Self::default();
444 map.insert(K::example(), V::example());
445 map
446 }
447}
448
449impl<T: std::cmp::Ord + AbiExample, S: AbiExample> AbiExample for BTreeMap<T, S> {
450 fn example() -> Self {
451 println!("AbiExample for (BTreeMap<T, S>): {}", type_name::<Self>());
452 let mut map = BTreeMap::default();
453 map.insert(T::example(), S::example());
454 map
455 }
456}
457
458impl<T: AbiExample> AbiExample for Vec<T> {
459 fn example() -> Self {
460 println!("AbiExample for (Vec<T>): {}", type_name::<Self>());
461 vec![T::example()]
462 }
463}
464
465impl<T: AbiExample> AbiExample for VecDeque<T> {
466 fn example() -> Self {
467 println!("AbiExample for (Vec<T>): {}", type_name::<Self>());
468 VecDeque::from(vec![T::example()])
469 }
470}
471
472impl<T: std::cmp::Eq + std::hash::Hash + AbiExample, H: std::hash::BuildHasher + Default> AbiExample
473 for HashSet<T, H>
474{
475 fn example() -> Self {
476 println!("AbiExample for (HashSet<T, H>): {}", type_name::<Self>());
477 let mut set: HashSet<T, H> = HashSet::default();
478 set.insert(T::example());
479 set
480 }
481}
482
483impl<T: std::cmp::Ord + AbiExample> AbiExample for BTreeSet<T> {
484 fn example() -> Self {
485 println!("AbiExample for (BTreeSet<T>): {}", type_name::<Self>());
486 let mut set: BTreeSet<T> = BTreeSet::default();
487 set.insert(T::example());
488 set
489 }
490}
491
492#[cfg(not(target_os = "solana"))]
493impl AbiExample for memmap2::MmapMut {
494 fn example() -> Self {
495 memmap2::MmapMut::map_anon(1).expect("failed to map the data file")
496 }
497}
498
499#[cfg(not(target_os = "solana"))]
500impl AbiExample for std::path::PathBuf {
501 fn example() -> Self {
502 std::path::PathBuf::from(String::example())
503 }
504}
505
506#[cfg(not(target_os = "solana"))]
507impl AbiExample for std::time::SystemTime {
508 fn example() -> Self {
509 std::time::SystemTime::UNIX_EPOCH
510 }
511}
512
513use std::net::{IpAddr, Ipv4Addr, SocketAddr};
514impl AbiExample for SocketAddr {
515 fn example() -> Self {
516 SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0)
517 }
518}
519
520impl AbiExample for IpAddr {
521 fn example() -> Self {
522 IpAddr::V4(Ipv4Addr::UNSPECIFIED)
523 }
524}
525
526pub trait AbiEnumVisitor: Serialize {
535 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult;
536}
537
538pub trait TransparentAsHelper {}
539pub trait EvenAsOpaque {
540 const TYPE_NAME_MATCHER: &'static str;
541}
542
543impl<T: Serialize + ?Sized> AbiEnumVisitor for T {
544 default fn visit_for_abi(&self, _digester: &mut AbiDigester) -> DigestResult {
545 unreachable!(
546 "AbiEnumVisitor must be implemented for {}",
547 type_name::<T>()
548 );
549 }
550}
551
552impl<T: Serialize + AbiExample> AbiEnumVisitor for T {
553 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
554 println!("AbiEnumVisitor for T: {}", type_name::<T>());
555 T::example()
558 .serialize(digester.create_new())
559 .map_err(DigestError::wrap_by_type::<T>)
560 }
561}
562
563impl<T: Serialize + ?Sized + AbiEnumVisitor> AbiEnumVisitor for &T {
567 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
568 println!("AbiEnumVisitor for &T: {}", type_name::<T>());
569 T::visit_for_abi(self, digester)
571 }
572}
573
574impl<T: Serialize + TransparentAsHelper> AbiEnumVisitor for &T {
577 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
578 println!(
579 "AbiEnumVisitor for (TransparentAsHelper): {}",
580 type_name::<T>()
581 );
582 self.serialize(digester.create_new())
583 .map_err(DigestError::wrap_by_type::<T>)
584 }
585}
586
587impl<T: Serialize + TransparentAsHelper + EvenAsOpaque> AbiEnumVisitor for &T {
590 default fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
591 let type_name = type_name::<T>();
592 let matcher = T::TYPE_NAME_MATCHER;
593 println!("AbiEnumVisitor for (EvenAsOpaque): {type_name}: matcher: {matcher}");
594 self.serialize(digester.create_new_opaque(matcher))
595 .map_err(DigestError::wrap_by_type::<T>)
596 }
597}
598
599impl<T: AbiEnumVisitor> AbiEnumVisitor for Option<T> {
602 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
603 println!("AbiEnumVisitor for (Option<T>): {}", type_name::<Self>());
604
605 let variant: Self = Option::Some(T::example());
606 variant.serialize(digester.create_new())
609 }
610}
611
612impl<O: AbiEnumVisitor, E: AbiEnumVisitor> AbiEnumVisitor for Result<O, E> {
613 fn visit_for_abi(&self, digester: &mut AbiDigester) -> DigestResult {
614 println!("AbiEnumVisitor for (Result<O, E>): {}", type_name::<Self>());
615
616 digester.update(&["enum Result (variants = 2)"]);
617 let variant: Self = Result::Ok(O::example());
618 variant.serialize(digester.create_enum_child()?)?;
619
620 let variant: Self = Result::Err(E::example());
621 variant.serialize(digester.create_enum_child()?)?;
622
623 digester.create_child()
624 }
625}
626
627#[cfg(not(target_os = "solana"))]
628impl<T: AbiExample> AbiExample for std::sync::OnceLock<T> {
629 fn example() -> Self {
630 Self::from(T::example())
631 }
632}
633
634#[cfg(not(target_os = "solana"))]
635impl<
636 T: std::cmp::Eq + std::hash::Hash + AbiExample,
637 S: AbiExample,
638 H: std::hash::BuildHasher + Default + std::clone::Clone,
639 > AbiExample for dashmap::DashMap<T, S, H>
640{
641 fn example() -> Self {
642 println!("AbiExample for (DashMap<T, S, H>): {}", type_name::<Self>());
643 let map = dashmap::DashMap::default();
644 map.insert(T::example(), S::example());
645 map
646 }
647}
648
649#[cfg(not(target_os = "solana"))]
650impl<T: AbiExample> AbiExample for boxcar::Vec<T> {
651 fn example() -> Self {
652 println!("AbiExample for (boxcar::Vec): {}", type_name::<Self>());
653 let vec = boxcar::Vec::new();
654 vec.push(T::example());
655 vec
656 }
657}