sov_universal_wallet/schema/
container.rs1use 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 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}