Skip to main content

sov_universal_wallet/schema/
container.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5use crate::ty::{ContainerSerdeMetadata, Enum, LinkingScheme, Struct, Tuple, Ty};
6
7#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub struct StructWithSerde<L: LinkingScheme> {
10    pub ty: Struct<L>,
11    pub serde: ContainerSerdeMetadata,
12}
13
14impl<L: LinkingScheme> From<Struct<L>> for StructWithSerde<L> {
15    fn from(value: Struct<L>) -> Self {
16        Self {
17            ty: value,
18            serde: ContainerSerdeMetadata::default(),
19        }
20    }
21}
22
23impl<L: LinkingScheme> From<StructWithSerde<L>> for Struct<L> {
24    fn from(value: StructWithSerde<L>) -> Self {
25        value.ty
26    }
27}
28
29#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31pub struct EnumWithSerde<L: LinkingScheme> {
32    pub ty: Enum<L>,
33    pub serde: ContainerSerdeMetadata,
34}
35
36impl<L: LinkingScheme> From<Enum<L>> for EnumWithSerde<L> {
37    fn from(value: Enum<L>) -> Self {
38        Self {
39            ty: value,
40            serde: ContainerSerdeMetadata::default(),
41        }
42    }
43}
44
45impl<L: LinkingScheme> From<EnumWithSerde<L>> for Enum<L> {
46    fn from(value: EnumWithSerde<L>) -> Self {
47        value.ty
48    }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum Container<L: LinkingScheme> {
53    Struct(StructWithSerde<L>),
54    Enum(EnumWithSerde<L>),
55    Tuple(Tuple<L>),
56    Option {
57        value: L::TypeLink,
58    },
59    Array {
60        len: usize,
61        value: L::TypeLink,
62    },
63    Vec {
64        value: L::TypeLink,
65    },
66    Map {
67        key: L::TypeLink,
68        value: L::TypeLink,
69    },
70}
71
72impl<L: LinkingScheme> Container<L> {
73    /// Returns the number of child types required by this container.
74    pub fn num_children(&self) -> usize {
75        match self {
76            Container::Struct(s) => s.ty.fields.len(),
77            Container::Enum(e) => {
78                e.ty.variants
79                    .iter()
80                    .map(|variant| match &variant.value {
81                        Some(_) => 1,
82                        _ => 0,
83                    })
84                    .sum()
85            }
86            Container::Tuple(t) => t.fields.len(),
87            Container::Option { .. } => 1,
88            Container::Array { .. } => 1,
89            Container::Vec { .. } => 1,
90            Container::Map { .. } => 2,
91        }
92    }
93
94    pub fn serde(&self) -> ContainerSerdeMetadata {
95        match self {
96            Container::Struct(s) => s.serde.clone(),
97            Container::Enum(e) => e.serde.clone(),
98            _ => ContainerSerdeMetadata::default(),
99        }
100    }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub struct ErrNotAContainer;
105
106impl<L: LinkingScheme> TryFrom<Ty<L>> for Container<L> {
107    type Error = ErrNotAContainer;
108
109    fn try_from(value: Ty<L>) -> Result<Self, Self::Error> {
110        match value {
111            Ty::Enum(e) => Ok(Container::Enum(e.into())),
112            Ty::Struct(s) => Ok(Container::Struct(s.into())),
113            Ty::Tuple(t) => Ok(Container::Tuple(t)),
114            Ty::Option { value } => Ok(Container::Option { value }),
115            Ty::Array { len, value } => Ok(Container::Array { len, value }),
116            Ty::Map { key, value } => Ok(Container::Map { key, value }),
117            Ty::Vec { value } => Ok(Container::Vec { value }),
118            _ => Err(ErrNotAContainer),
119        }
120    }
121}
122
123impl<L: LinkingScheme> From<Container<L>> for Ty<L> {
124    fn from(value: Container<L>) -> Self {
125        match value {
126            Container::Struct(s) => Ty::Struct(s.into()),
127            Container::Enum(e) => Ty::Enum(e.into()),
128            Container::Tuple(t) => Ty::Tuple(t),
129            Container::Option { value } => Ty::Option { value },
130            Container::Array { len, value } => Ty::Array { len, value },
131            Container::Vec { value } => Ty::Vec { value },
132            Container::Map { key, value } => Ty::Map { key, value },
133        }
134    }
135}