sbor/schema/type_data/
type_metadata.rs1use borrow::Borrow;
2
3use crate::rust::prelude::*;
4use crate::*;
5
6#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
8pub struct NovelTypeMetadata {
9 pub type_hash: TypeHash,
10 pub type_metadata: TypeMetadata,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
16pub struct TypeMetadata {
17 pub type_name: Option<Cow<'static, str>>,
18 pub child_names: Option<ChildNames>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
22pub enum ChildNames {
23 NamedFields(Vec<Cow<'static, str>>),
24 EnumVariants(IndexMap<u8, TypeMetadata>),
25}
26
27impl TypeMetadata {
28 pub fn unnamed() -> Self {
29 Self {
30 type_name: None,
31 child_names: None,
32 }
33 }
34
35 pub fn no_child_names(name: &'static str) -> Self {
36 Self {
37 type_name: Some(Cow::Borrowed(name)),
38 child_names: None,
39 }
40 }
41
42 pub fn struct_fields(name: &'static str, field_names: &[&'static str]) -> Self {
43 let field_names = field_names
44 .iter()
45 .map(|field_name| Cow::Borrowed(*field_name))
46 .collect();
47 Self {
48 type_name: Some(Cow::Borrowed(name)),
49 child_names: Some(ChildNames::NamedFields(field_names)),
50 }
51 }
52
53 pub fn enum_variants(name: &'static str, variant_naming: IndexMap<u8, TypeMetadata>) -> Self {
54 Self {
55 type_name: Some(Cow::Borrowed(name)),
56 child_names: Some(ChildNames::EnumVariants(variant_naming)),
57 }
58 }
59
60 pub fn with_name(mut self, name: Option<Cow<'static, str>>) -> Self {
61 self.type_name = name;
62 self
63 }
64
65 pub fn with_type_hash(self, type_hash: TypeHash) -> NovelTypeMetadata {
66 NovelTypeMetadata {
67 type_hash,
68 type_metadata: self,
69 }
70 }
71
72 pub fn get_name(&self) -> Option<&str> {
73 self.type_name.as_ref().map(|c| c.as_ref())
74 }
75
76 pub fn get_name_string(&self) -> Option<String> {
77 self.type_name.as_ref().map(|c| c.to_string())
78 }
79
80 pub fn get_field_names<'a>(&'a self) -> Option<&'a [Cow<'static, str>]> {
81 match &self.child_names {
82 Some(ChildNames::NamedFields(field_names)) => Some(field_names.as_slice()),
83 _ => None,
84 }
85 }
86
87 pub fn get_field_name<'a>(&'a self, field_index: usize) -> Option<&'a str> {
88 match &self.child_names {
89 Some(ChildNames::NamedFields(field_names)) => {
90 Some(field_names.get(field_index)?.borrow())
91 }
92 _ => None,
93 }
94 }
95
96 pub fn get_enum_variant_data<'a>(&'a self, discriminator: u8) -> Option<&'a TypeMetadata> {
97 match &self.child_names {
98 Some(ChildNames::EnumVariants(variants)) => variants.get(&discriminator),
99 _ => None,
100 }
101 }
102
103 pub fn get_matching_tuple_data(&self, fields_length: usize) -> TupleData {
104 TupleData {
105 name: self.get_name(),
106 field_names: self
107 .get_field_names()
108 .filter(|field_names| field_names.len() == fields_length),
109 }
110 }
111
112 pub fn get_matching_enum_variant_data(
113 &self,
114 variant_id: u8,
115 fields_length: usize,
116 ) -> EnumVariantData {
117 let enum_name = self.get_name();
118 let Some(ChildNames::EnumVariants(variants)) = &self.child_names else {
119 return EnumVariantData {
120 enum_name,
121 variant_name: None,
122 field_names: None,
123 };
124 };
125 let Some(variant_metadata) = variants.get(&variant_id) else {
126 return EnumVariantData {
127 enum_name,
128 variant_name: None,
129 field_names: None,
130 };
131 };
132 EnumVariantData {
133 enum_name,
134 variant_name: variant_metadata.get_name(),
135 field_names: variant_metadata
136 .get_field_names()
137 .filter(|field_names| field_names.len() == fields_length),
138 }
139 }
140}
141
142#[derive(Debug, Default)]
143pub struct TupleData<'s> {
144 pub name: Option<&'s str>,
145 pub field_names: Option<&'s [Cow<'static, str>]>,
146}
147
148#[derive(Debug, Default)]
149pub struct EnumVariantData<'s> {
150 pub enum_name: Option<&'s str>,
151 pub variant_name: Option<&'s str>,
152 pub field_names: Option<&'s [Cow<'static, str>]>,
153}