1#![allow(dead_code)] use crate as borsh; use crate::__private::maybestd::{
17 borrow,
18 boxed::Box,
19 collections::{btree_map::Entry, BTreeMap, BTreeSet, LinkedList, VecDeque},
20 format,
21 string::{String, ToString},
22 vec,
23 vec::Vec,
24};
25use crate::io::{Read, Result as IOResult, Write};
26use crate::{BorshDeserialize, BorshSchema as BorshSchemaMacro, BorshSerialize};
27use core::borrow::Borrow;
28use core::cmp::Ord;
29use core::marker::PhantomData;
30
31mod container_ext;
32
33pub use container_ext::{SchemaContainerValidateError, SchemaMaxSerializedSizeError};
34
35pub type Declaration = String;
37pub type VariantName = String;
39pub type DiscriminantValue = i64;
41pub type FieldName = String;
43#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize, BorshSchemaMacro)]
47pub enum Definition {
48 Primitive(u8),
50
51 Sequence {
74 length_width: u8,
80
81 length_range: core::ops::RangeInclusive<u64>,
87
88 elements: Declaration,
90 },
91
92 Tuple { elements: Vec<Declaration> },
95
96 Enum {
107 tag_width: u8,
114
115 variants: Vec<(DiscriminantValue, VariantName, Declaration)>,
118 },
119
120 Struct { fields: Fields },
122}
123
124impl Definition {
125 pub const ARRAY_LENGTH_WIDTH: u8 = 0;
128
129 pub const DEFAULT_LENGTH_WIDTH: u8 = 4;
134
135 pub const DEFAULT_LENGTH_RANGE: core::ops::RangeInclusive<u64> = 0..=(u32::MAX as u64);
141}
142
143#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize, BorshSchemaMacro)]
145pub enum Fields {
146 NamedFields(Vec<(FieldName, Declaration)>),
149 UnnamedFields(Vec<Declaration>),
151 Empty,
153}
154
155#[derive(Clone, PartialEq, Eq, Debug)]
157pub struct BorshSchemaContainer {
158 declaration: Declaration,
160 definitions: BTreeMap<Declaration, Definition>,
162}
163
164impl BorshSchemaContainer {
165 pub fn new(declaration: Declaration, definitions: BTreeMap<Declaration, Definition>) -> Self {
166 Self {
167 declaration,
168 definitions,
169 }
170 }
171
172 pub fn for_type<T: BorshSchema + ?Sized>() -> Self {
174 let mut definitions = Default::default();
175 T::add_definitions_recursively(&mut definitions);
176 Self::new(T::declaration(), definitions)
177 }
178
179 pub fn declaration(&self) -> &Declaration {
180 &self.declaration
181 }
182 pub fn definitions(&self) -> impl Iterator<Item = (&'_ Declaration, &'_ Definition)> {
183 self.definitions.iter()
184 }
185
186 pub fn get_definition<Q>(&self, declaration: &Q) -> Option<&Definition>
187 where
188 Declaration: Borrow<Q>,
189 Q: Ord + ?Sized,
190 {
191 self.definitions.get(declaration)
192 }
193
194 pub fn get_mut_definition<Q>(&mut self, declaration: &Q) -> Option<&mut Definition>
195 where
196 Declaration: Borrow<Q>,
197 Q: Ord + ?Sized,
198 {
199 self.definitions.get_mut(declaration)
200 }
201
202 pub fn insert_definition(
203 &mut self,
204 declaration: Declaration,
205 definition: Definition,
206 ) -> Option<Definition> {
207 self.definitions.insert(declaration, definition)
208 }
209 pub fn remove_definition<Q>(&mut self, declaration: &Q) -> Option<Definition>
210 where
211 Declaration: Borrow<Q>,
212 Q: Ord + ?Sized,
213 {
214 self.definitions.remove(declaration)
215 }
216}
217
218impl BorshSerialize for BorshSchemaContainer
219where
220 Declaration: BorshSerialize,
221 BTreeMap<Declaration, Definition>: BorshSerialize,
222{
223 fn serialize<W: Write>(&self, writer: &mut W) -> IOResult<()> {
224 let declaration = self.declaration();
225 let definitions: BTreeMap<&Declaration, &Definition> = self.definitions().collect();
226 BorshSerialize::serialize(declaration, writer)?;
227 BorshSerialize::serialize(&definitions, writer)?;
228 Ok(())
229 }
230}
231
232impl BorshDeserialize for BorshSchemaContainer
233where
234 Declaration: BorshDeserialize,
235 BTreeMap<Declaration, Definition>: BorshDeserialize,
236{
237 fn deserialize_reader<R: Read>(reader: &mut R) -> IOResult<Self> {
238 let declaration: Declaration = BorshDeserialize::deserialize_reader(reader)?;
239 let definitions: BTreeMap<Declaration, Definition> =
240 BorshDeserialize::deserialize_reader(reader)?;
241 Ok(Self::new(declaration, definitions))
242 }
243}
244
245pub fn add_definition(
247 declaration: Declaration,
248 definition: Definition,
249 definitions: &mut BTreeMap<Declaration, Definition>,
250) {
251 match definitions.entry(declaration) {
252 Entry::Occupied(occ) => {
253 let existing_def = occ.get();
254 assert_eq!(
255 existing_def,
256 &definition,
257 "Redefining type schema for {}. Types with the same names are not supported.",
258 occ.key()
259 );
260 }
261 Entry::Vacant(vac) => {
262 vac.insert(definition);
263 }
264 }
265}
266
267pub trait BorshSchema {
270 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>);
273
274 fn declaration() -> Declaration;
276}
277
278impl BorshSchema for BorshSchemaContainer
279where
280 Declaration: BorshSchema,
281 BTreeMap<Declaration, Definition>: BorshSchema,
282{
283 fn declaration() -> Declaration {
284 "BorshSchemaContainer".to_string()
285 }
286 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
287 let fields = Fields::NamedFields(<[_]>::into_vec(Box::new([
288 (
289 "declaration".to_string(),
290 <Declaration as BorshSchema>::declaration(),
291 ),
292 (
293 "definitions".to_string(),
294 <BTreeMap<Declaration, Definition> as BorshSchema>::declaration(),
295 ),
296 ])));
297 let definition = Definition::Struct { fields };
298 add_definition(
299 <Self as BorshSchema>::declaration(),
300 definition,
301 definitions,
302 );
303 <Declaration as BorshSchema>::add_definitions_recursively(definitions);
304 <BTreeMap<Declaration, Definition> as BorshSchema>::add_definitions_recursively(
305 definitions,
306 );
307 }
308}
309impl<T> BorshSchema for Box<T>
310where
311 T: BorshSchema + ?Sized,
312{
313 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
314 T::add_definitions_recursively(definitions);
315 }
316
317 fn declaration() -> Declaration {
318 T::declaration()
319 }
320}
321
322impl<T> BorshSchema for core::cell::Cell<T>
323where
324 T: BorshSchema + Copy,
325{
326 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
327 T::add_definitions_recursively(definitions);
328 }
329
330 fn declaration() -> Declaration {
331 T::declaration()
332 }
333}
334
335impl<T> BorshSchema for core::cell::RefCell<T>
336where
337 T: BorshSchema + Sized,
338{
339 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
340 T::add_definitions_recursively(definitions);
341 }
342
343 fn declaration() -> Declaration {
344 T::declaration()
345 }
346}
347#[cfg(feature = "rc")]
349pub mod rc {
350 use crate::BorshSchema;
354
355 use super::{Declaration, Definition};
356 use crate::__private::maybestd::collections::BTreeMap;
357 use crate::__private::maybestd::{rc::Rc, sync::Arc};
358
359 impl<T> BorshSchema for Rc<T>
360 where
361 T: BorshSchema + ?Sized,
362 {
363 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
364 T::add_definitions_recursively(definitions);
365 }
366
367 fn declaration() -> Declaration {
368 T::declaration()
369 }
370 }
371
372 impl<T> BorshSchema for Arc<T>
373 where
374 T: BorshSchema + ?Sized,
375 {
376 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
377 T::add_definitions_recursively(definitions);
378 }
379
380 fn declaration() -> Declaration {
381 T::declaration()
382 }
383 }
384}
385
386impl<T> BorshSchema for borrow::Cow<'_, T>
387where
388 T: borrow::ToOwned + ?Sized,
389 T::Owned: BorshSchema,
390{
391 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
392 <T::Owned as BorshSchema>::add_definitions_recursively(definitions);
393 }
394
395 fn declaration() -> Declaration {
396 <T::Owned as BorshSchema>::declaration()
397 }
398}
399
400macro_rules! impl_for_renamed_primitives {
401 ($($ty: ty : $name: ident => $size: expr);+) => {
402 $(
403 impl BorshSchema for $ty {
404 #[inline]
405 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
406 let definition = Definition::Primitive($size);
407 add_definition(Self::declaration(), definition, definitions);
408 }
409 #[inline]
410 fn declaration() -> Declaration { stringify!($name).into() }
411 }
412 )+
413 };
414
415 ($($ty: ty : $name: expr, $size: expr);+) => {
416 $(
417 impl BorshSchema for $ty {
418 #[inline]
419 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
420 let definition = Definition::Primitive($size);
421 add_definition(Self::declaration(), definition, definitions);
422 }
423 #[inline]
424 fn declaration() -> Declaration { $name.into() }
425 }
426 )+
427 };
428}
429
430macro_rules! impl_for_primitives {
431 ($($ty: ident => $size: expr);+) => {
432 impl_for_renamed_primitives!{$($ty : $ty => $size);+}
433 };
434}
435
436impl_for_primitives!(bool => 1; f32 => 4; f64 => 8; i8 => 1; i16 => 2; i32 => 4; i64 => 8; i128 => 16);
437impl_for_primitives!(u8 => 1; u16 => 2; u32 => 4; u64 => 8; u128 => 16);
438impl_for_renamed_primitives!(isize: i64 => 8);
439impl_for_renamed_primitives!(usize: u64 => 8);
440
441impl_for_renamed_primitives!(core::num::NonZeroI8: NonZeroI8 => 1);
442impl_for_renamed_primitives!(core::num::NonZeroI16: NonZeroI16 => 2);
443impl_for_renamed_primitives!(core::num::NonZeroI32: NonZeroI32 => 4);
444impl_for_renamed_primitives!(core::num::NonZeroI64: NonZeroI64 => 8);
445impl_for_renamed_primitives!(core::num::NonZeroI128: NonZeroI128 => 16);
446impl_for_renamed_primitives!(core::num::NonZeroU8: NonZeroU8 => 1);
447impl_for_renamed_primitives!(core::num::NonZeroU16: NonZeroU16 => 2);
448impl_for_renamed_primitives!(core::num::NonZeroU32: NonZeroU32 => 4);
449impl_for_renamed_primitives!(core::num::NonZeroU64: NonZeroU64 => 8);
450impl_for_renamed_primitives!(core::num::NonZeroU128: NonZeroU128 => 16);
451impl_for_renamed_primitives!(core::num::NonZeroUsize: NonZeroUsize => 8);
453
454impl_for_renamed_primitives!((): "()", 0);
455
456impl BorshSchema for String {
457 #[inline]
458 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
459 str::add_definitions_recursively(definitions);
460 }
461 #[inline]
462 fn declaration() -> Declaration {
463 str::declaration()
464 }
465}
466
467impl BorshSchema for str {
468 #[inline]
469 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
470 let definition = Definition::Sequence {
471 length_width: Definition::DEFAULT_LENGTH_WIDTH,
472 length_range: Definition::DEFAULT_LENGTH_RANGE,
473 elements: u8::declaration(),
474 };
475 add_definition(Self::declaration(), definition, definitions);
476 u8::add_definitions_recursively(definitions);
477 }
478 #[inline]
479 fn declaration() -> Declaration {
480 "String".into()
481 }
482}
483
484#[cfg(feature = "ascii")]
486pub mod ascii {
487 use crate::BorshSchema;
491
492 use super::{add_definition, Declaration, Definition};
493 use crate::__private::maybestd::collections::BTreeMap;
494
495 impl BorshSchema for ascii::AsciiString {
496 #[inline]
497 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
498 ascii::AsciiStr::add_definitions_recursively(definitions);
499 }
500 #[inline]
501 fn declaration() -> Declaration {
502 ascii::AsciiStr::declaration()
503 }
504 }
505
506 impl BorshSchema for ascii::AsciiStr {
507 #[inline]
508 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
509 let definition = Definition::Sequence {
510 length_width: Definition::DEFAULT_LENGTH_WIDTH,
511 length_range: Definition::DEFAULT_LENGTH_RANGE,
512 elements: ascii::AsciiChar::declaration(),
513 };
514 add_definition(Self::declaration(), definition, definitions);
515 ascii::AsciiChar::add_definitions_recursively(definitions);
516 }
517 #[inline]
518 fn declaration() -> Declaration {
519 "AsciiString".into()
520 }
521 }
522
523 impl BorshSchema for ascii::AsciiChar {
524 #[inline]
525 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
526 add_definition(Self::declaration(), Definition::Primitive(1), definitions);
527 }
528 #[inline]
529 fn declaration() -> Declaration {
530 "AsciiChar".into()
531 }
532 }
533}
534
535impl BorshSchema for core::ops::RangeFull {
536 #[inline]
537 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
538 let fields = Fields::Empty;
539 let def = Definition::Struct { fields };
540 add_definition(Self::declaration(), def, definitions);
541 }
542 #[inline]
543 fn declaration() -> Declaration {
544 "RangeFull".into()
545 }
546}
547
548macro_rules! impl_for_range {
549 ($type:ident, $($name:ident),*) => {
550 impl<T: BorshSchema> BorshSchema for core::ops::$type<T> {
551 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
552 let decl = T::declaration();
553 let fields = Fields::NamedFields(vec![$(
554 (FieldName::from(stringify!($name)), decl.clone())
555 ),*]);
556 let def = Definition::Struct { fields };
557 add_definition(Self::declaration(), def, definitions);
558 T::add_definitions_recursively(definitions);
559 }
560 fn declaration() -> Declaration {
561 format!("{}<{}>", stringify!($type), T::declaration())
562 }
563 }
564 };
565}
566
567impl_for_range!(Range, start, end);
568impl_for_range!(RangeInclusive, start, end);
569impl_for_range!(RangeFrom, start);
570impl_for_range!(RangeTo, end);
571impl_for_range!(RangeToInclusive, end);
572
573impl<T, const N: usize> BorshSchema for [T; N]
574where
575 T: BorshSchema,
576{
577 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
578 use core::convert::TryFrom;
579 let length = u64::try_from(N).unwrap();
580 let definition = Definition::Sequence {
581 length_width: Definition::ARRAY_LENGTH_WIDTH,
582 length_range: length..=length,
583 elements: T::declaration(),
584 };
585 add_definition(Self::declaration(), definition, definitions);
586 T::add_definitions_recursively(definitions);
587 }
588 fn declaration() -> Declaration {
589 format!(r#"[{}; {}]"#, T::declaration(), N)
590 }
591}
592
593impl<T> BorshSchema for Option<T>
594where
595 T: BorshSchema,
596{
597 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
598 let definition = Definition::Enum {
599 tag_width: 1,
600 variants: vec![
601 (0u8 as i64, "None".to_string(), <()>::declaration()),
602 (1u8 as i64, "Some".to_string(), T::declaration()),
603 ],
604 };
605 add_definition(Self::declaration(), definition, definitions);
606 T::add_definitions_recursively(definitions);
607 <()>::add_definitions_recursively(definitions);
608 }
609
610 fn declaration() -> Declaration {
611 format!(r#"Option<{}>"#, T::declaration())
612 }
613}
614
615impl<T, E> BorshSchema for core::result::Result<T, E>
616where
617 T: BorshSchema,
618 E: BorshSchema,
619{
620 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
621 let definition = Definition::Enum {
622 tag_width: 1,
623 variants: vec![
624 (1u8 as i64, "Ok".to_string(), T::declaration()),
625 (0u8 as i64, "Err".to_string(), E::declaration()),
626 ],
627 };
628 add_definition(Self::declaration(), definition, definitions);
629 T::add_definitions_recursively(definitions);
630 E::add_definitions_recursively(definitions);
631 }
632
633 fn declaration() -> Declaration {
634 format!(r#"Result<{}, {}>"#, T::declaration(), E::declaration())
635 }
636}
637
638macro_rules! impl_for_vec_like_collection {
639 ($type: ident) => {
640 impl<T> BorshSchema for $type<T>
641 where
642 T: BorshSchema,
643 {
644 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
645 let definition = Definition::Sequence {
646 length_width: Definition::DEFAULT_LENGTH_WIDTH,
647 length_range: Definition::DEFAULT_LENGTH_RANGE,
648 elements: T::declaration(),
649 };
650 add_definition(Self::declaration(), definition, definitions);
651 T::add_definitions_recursively(definitions);
652 }
653
654 fn declaration() -> Declaration {
655 format!(r#"{}<{}>"#, stringify!($type), T::declaration())
656 }
657 }
658 };
659}
660
661impl_for_vec_like_collection!(Vec);
662impl_for_vec_like_collection!(VecDeque);
663impl_for_vec_like_collection!(LinkedList);
664
665impl<T> BorshSchema for [T]
666where
667 T: BorshSchema,
668{
669 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
670 let definition = Definition::Sequence {
671 length_width: Definition::DEFAULT_LENGTH_WIDTH,
672 length_range: Definition::DEFAULT_LENGTH_RANGE,
673 elements: T::declaration(),
674 };
675 add_definition(Self::declaration(), definition, definitions);
676 T::add_definitions_recursively(definitions);
677 }
678
679 fn declaration() -> Declaration {
680 format!(r#"Vec<{}>"#, T::declaration())
681 }
682}
683
684#[cfg(hash_collections)]
689pub mod hashes {
690 use crate::BorshSchema;
691
692 use super::{add_definition, Declaration, Definition};
693 use crate::__private::maybestd::collections::BTreeMap;
694
695 use crate::__private::maybestd::collections::{HashMap, HashSet};
696 #[cfg(not(feature = "std"))]
697 use alloc::format;
698
699 impl<K, V, S> BorshSchema for HashMap<K, V, S>
704 where
705 K: BorshSchema,
706 V: BorshSchema,
707 {
708 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
709 let definition = Definition::Sequence {
710 length_width: Definition::DEFAULT_LENGTH_WIDTH,
711 length_range: Definition::DEFAULT_LENGTH_RANGE,
712 elements: <(K, V)>::declaration(),
713 };
714 add_definition(Self::declaration(), definition, definitions);
715 <(K, V)>::add_definitions_recursively(definitions);
716 }
717
718 fn declaration() -> Declaration {
719 format!(r#"HashMap<{}, {}>"#, K::declaration(), V::declaration())
720 }
721 }
722
723 impl<T, S> BorshSchema for HashSet<T, S>
724 where
725 T: BorshSchema,
726 {
727 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
728 let definition = Definition::Sequence {
729 length_width: Definition::DEFAULT_LENGTH_WIDTH,
730 length_range: Definition::DEFAULT_LENGTH_RANGE,
731 elements: <T>::declaration(),
732 };
733 add_definition(Self::declaration(), definition, definitions);
734 <T>::add_definitions_recursively(definitions);
735 }
736
737 fn declaration() -> Declaration {
738 format!(r#"HashSet<{}>"#, T::declaration())
739 }
740 }
741}
742
743impl<K, V> BorshSchema for BTreeMap<K, V>
744where
745 K: BorshSchema,
746 V: BorshSchema,
747{
748 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
749 let definition = Definition::Sequence {
750 length_width: Definition::DEFAULT_LENGTH_WIDTH,
751 length_range: Definition::DEFAULT_LENGTH_RANGE,
752 elements: <(K, V)>::declaration(),
753 };
754 add_definition(Self::declaration(), definition, definitions);
755 <(K, V)>::add_definitions_recursively(definitions);
756 }
757
758 fn declaration() -> Declaration {
759 format!(r#"BTreeMap<{}, {}>"#, K::declaration(), V::declaration())
760 }
761}
762
763impl<T> BorshSchema for BTreeSet<T>
764where
765 T: BorshSchema,
766{
767 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
768 let definition = Definition::Sequence {
769 length_width: Definition::DEFAULT_LENGTH_WIDTH,
770 length_range: Definition::DEFAULT_LENGTH_RANGE,
771 elements: <T>::declaration(),
772 };
773 add_definition(Self::declaration(), definition, definitions);
774 <T>::add_definitions_recursively(definitions);
775 }
776
777 fn declaration() -> Declaration {
778 format!(r#"BTreeSet<{}>"#, T::declaration())
779 }
780}
781
782impl<T> BorshSchema for PhantomData<T> {
785 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
786 <()>::add_definitions_recursively(definitions);
787 }
788
789 fn declaration() -> Declaration {
790 <()>::declaration()
791 }
792}
793
794macro_rules! impl_tuple {
795 ($($name:ident),+) => {
796 impl<$($name),+> BorshSchema for ($($name,)+)
797 where
798 $($name: BorshSchema),+
799 {
800 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
801 let elements = vec![$($name::declaration()),+];
802
803 let definition = Definition::Tuple { elements };
804 add_definition(Self::declaration(), definition, definitions);
805 $(
806 $name::add_definitions_recursively(definitions);
807 )+
808 }
809
810 fn declaration() -> Declaration {
811 let params = vec![$($name::declaration()),+];
812 if params.len() == 1 {
813 format!(r#"({},)"#, params[0])
814 } else {
815 format!(r#"({})"#, params.join(", "))
816 }
817 }
818 }
819 };
820}
821
822impl_tuple!(T0);
823impl_tuple!(T0, T1);
824impl_tuple!(T0, T1, T2);
825impl_tuple!(T0, T1, T2, T3);
826impl_tuple!(T0, T1, T2, T3, T4);
827impl_tuple!(T0, T1, T2, T3, T4, T5);
828impl_tuple!(T0, T1, T2, T3, T4, T5, T6);
829impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7);
830impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
831impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
832impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
833impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
834impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
835impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
836impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
837impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
838impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
839impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17);
840impl_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18);
841impl_tuple!(
842 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19
843);
844impl_tuple!(
845 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20
846);
847
848#[cfg(feature = "std")]
849mod ip_addr_std_derive_impl {
850 use crate::BorshSchema as BorshSchemaMacro;
851
852 #[derive(BorshSchemaMacro)]
853 #[borsh(crate = "crate")]
854 pub struct Ipv4Addr {
855 octets: [u8; 4],
856 }
857
858 #[derive(BorshSchemaMacro)]
859 #[borsh(crate = "crate")]
860 pub struct Ipv6Addr {
861 octets: [u8; 16],
862 }
863
864 #[derive(BorshSchemaMacro)]
865 #[borsh(crate = "crate")]
866 pub enum IpAddr {
867 V4(core::net::Ipv4Addr),
869 V6(core::net::Ipv6Addr),
871 }
872}
873
874#[cfg(feature = "std")]
875impl BorshSchema for core::net::Ipv4Addr {
876 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
877 <ip_addr_std_derive_impl::Ipv4Addr>::add_definitions_recursively(definitions);
878 }
879
880 fn declaration() -> Declaration {
881 ip_addr_std_derive_impl::Ipv4Addr::declaration()
882 }
883}
884
885#[cfg(feature = "std")]
886impl BorshSchema for core::net::Ipv6Addr {
887 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
888 <ip_addr_std_derive_impl::Ipv6Addr>::add_definitions_recursively(definitions);
889 }
890
891 fn declaration() -> Declaration {
892 ip_addr_std_derive_impl::Ipv6Addr::declaration()
893 }
894}
895
896#[cfg(feature = "std")]
897impl BorshSchema for core::net::IpAddr {
898 fn add_definitions_recursively(definitions: &mut BTreeMap<Declaration, Definition>) {
899 <ip_addr_std_derive_impl::IpAddr>::add_definitions_recursively(definitions);
900 }
901
902 fn declaration() -> Declaration {
903 ip_addr_std_derive_impl::IpAddr::declaration()
904 }
905}