1use crate::rust::prelude::*;
2use crate::*;
3
4define_single_versioned!(
5 #[derive(Debug, Clone, PartialEq, Eq, Sbor)]
6 #[sbor(child_types = "S::CustomLocalTypeKind; S::CustomTypeValidation")]
7 pub VersionedSchema(SchemaVersions)<S: CustomSchema> => Schema<S> = SchemaV1::<S>
8);
9
10impl<S: CustomSchema> VersionedSchema<S> {
11 pub fn v1(&self) -> &SchemaV1<S> {
12 self.as_unique_version()
13 }
14
15 pub fn v1_mut(&mut self) -> &mut SchemaV1<S> {
16 self.as_unique_version_mut()
17 }
18}
19
20impl<S: CustomSchema> VersionedSchema<S> {
21 pub fn empty() -> Self {
22 Schema::empty().into()
23 }
24}
25
26impl<S: CustomSchema> Default for VersionedSchema<S> {
27 fn default() -> Self {
28 Self::empty()
29 }
30}
31
32#[derive(Debug, Clone, Sbor)]
35#[sbor(child_types = "S::CustomLocalTypeKind; S::CustomTypeValidation")]
36pub struct SingleTypeSchema<S: CustomSchema> {
37 pub schema: VersionedSchema<S>,
38 pub type_id: LocalTypeId,
39}
40
41impl<S: CustomSchema> SingleTypeSchema<S> {
42 pub fn new(schema: VersionedSchema<S>, type_id: LocalTypeId) -> Self {
43 Self { schema, type_id }
44 }
45
46 pub fn from<T: IntoComparableSchema<Self, S>>(from: T) -> Self {
47 from.into_schema()
48 }
49
50 pub fn for_type<T: Describe<S::CustomAggregatorTypeKind> + ?Sized>() -> Self {
51 generate_single_type_schema::<T, S>()
52 }
53}
54
55#[derive(Debug, Clone, Sbor)]
61#[sbor(child_types = "S::CustomLocalTypeKind; S::CustomTypeValidation")]
62pub struct TypeCollectionSchema<S: CustomSchema> {
63 pub schema: VersionedSchema<S>,
64 pub type_ids: IndexMap<String, LocalTypeId>,
65}
66
67impl<S: CustomSchema> TypeCollectionSchema<S> {
68 pub fn new(schema: VersionedSchema<S>, type_ids: IndexMap<String, LocalTypeId>) -> Self {
69 Self { schema, type_ids }
70 }
71
72 pub fn from<T: IntoComparableSchema<Self, S>>(from: T) -> Self {
73 from.into_schema()
74 }
75
76 pub fn from_aggregator(aggregator: TypeAggregator<S::CustomAggregatorTypeKind>) -> Self {
77 aggregator.generate_type_collection_schema::<S>()
78 }
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
83#[sbor(child_types = "S::CustomLocalTypeKind; S::CustomTypeValidation")]
88pub struct SchemaV1<S: CustomSchema> {
89 pub type_kinds: Vec<LocalTypeKind<S>>,
90 pub type_metadata: Vec<TypeMetadata>, pub type_validations: Vec<TypeValidation<S::CustomTypeValidation>>,
92}
93
94impl<S: CustomSchema> SchemaV1<S> {
95 pub fn empty() -> Self {
96 Self {
97 type_kinds: vec![],
98 type_metadata: vec![],
99 type_validations: vec![],
100 }
101 }
102
103 pub fn resolve_type_kind(&self, type_id: LocalTypeId) -> Option<&LocalTypeKind<S>> {
104 match type_id {
105 LocalTypeId::WellKnown(index) => {
106 S::resolve_well_known_type(index).map(|data| &data.kind)
107 }
108 LocalTypeId::SchemaLocalIndex(index) => self.type_kinds.get(index),
109 }
110 }
111
112 pub fn resolve_type_metadata(&self, type_id: LocalTypeId) -> Option<&TypeMetadata> {
113 match type_id {
114 LocalTypeId::WellKnown(index) => {
115 S::resolve_well_known_type(index).map(|data| &data.metadata)
116 }
117 LocalTypeId::SchemaLocalIndex(index) => self.type_metadata.get(index),
118 }
119 }
120
121 pub fn resolve_matching_tuple_metadata(
122 &self,
123 type_id: LocalTypeId,
124 fields_length: usize,
125 ) -> TupleData<'_> {
126 self.resolve_type_metadata(type_id)
127 .map(|m| m.get_matching_tuple_data(fields_length))
128 .unwrap_or_default()
129 }
130
131 pub fn resolve_matching_enum_metadata(
132 &self,
133 type_id: LocalTypeId,
134 variant_id: u8,
135 fields_length: usize,
136 ) -> EnumVariantData<'_> {
137 self.resolve_type_metadata(type_id)
138 .map(|m| m.get_matching_enum_variant_data(variant_id, fields_length))
139 .unwrap_or_default()
140 }
141
142 pub fn resolve_matching_array_metadata(&self, type_id: LocalTypeId) -> ArrayData<'_> {
143 let Some(TypeKind::Array { element_type }) = self.resolve_type_kind(type_id) else {
144 return ArrayData::default();
145 };
146 ArrayData {
147 array_name: self
148 .resolve_type_metadata(type_id)
149 .and_then(|m| m.get_name()),
150 element_name: self
151 .resolve_type_metadata(*element_type)
152 .and_then(|m| m.get_name()),
153 }
154 }
155
156 pub fn resolve_matching_map_metadata(&self, type_id: LocalTypeId) -> MapData<'_> {
157 let Some(TypeKind::Map {
158 key_type,
159 value_type,
160 }) = self.resolve_type_kind(type_id)
161 else {
162 return MapData::default();
163 };
164 MapData {
165 map_name: self
166 .resolve_type_metadata(type_id)
167 .and_then(|m| m.get_name()),
168 key_name: self
169 .resolve_type_metadata(*key_type)
170 .and_then(|m| m.get_name()),
171 value_name: self
172 .resolve_type_metadata(*value_type)
173 .and_then(|m| m.get_name()),
174 }
175 }
176
177 pub fn resolve_type_name_from_metadata(&self, type_id: LocalTypeId) -> Option<&'_ str> {
178 self.resolve_type_metadata(type_id)
179 .and_then(|m| m.get_name())
180 }
181
182 pub fn resolve_type_validation(
183 &self,
184 type_id: LocalTypeId,
185 ) -> Option<&TypeValidation<S::CustomTypeValidation>> {
186 match type_id {
187 LocalTypeId::WellKnown(index) => {
188 S::resolve_well_known_type(index).map(|data| &data.validation)
189 }
190 LocalTypeId::SchemaLocalIndex(index) => self.type_validations.get(index),
191 }
192 }
193
194 #[allow(clippy::type_complexity)]
195 pub fn resolve_type_data(
196 &self,
197 type_id: LocalTypeId,
198 ) -> Option<(
199 &LocalTypeKind<S>,
200 &TypeMetadata,
201 &TypeValidation<S::CustomTypeValidation>,
202 )> {
203 match type_id {
204 LocalTypeId::WellKnown(index) => {
205 let type_data = S::resolve_well_known_type(index)?;
206 Some((&type_data.kind, &type_data.metadata, &type_data.validation))
207 }
208 LocalTypeId::SchemaLocalIndex(index) => {
209 let type_kind = self.type_kinds.get(index)?;
210 let type_metadata = self.type_metadata.get(index)?;
211 let type_validation = self.type_validations.get(index)?;
212 Some((type_kind, type_metadata, type_validation))
213 }
214 }
215 }
216
217 pub fn validate(&self) -> Result<(), SchemaValidationError> {
218 validate_schema(self)
219 }
220}
221
222impl<S: CustomSchema> Default for SchemaV1<S> {
223 fn default() -> Self {
224 Self::empty()
225 }
226}
227
228#[derive(Debug, Default)]
229pub struct ArrayData<'m> {
230 pub array_name: Option<&'m str>,
231 pub element_name: Option<&'m str>,
232}
233
234#[derive(Debug, Default)]
235pub struct MapData<'m> {
236 pub map_name: Option<&'m str>,
237 pub key_name: Option<&'m str>,
238 pub value_name: Option<&'m str>,
239}