eas_sdk_rs/
schema.rs

1use std::fmt::{self, Display};
2
3#[derive(Debug, Clone)]
4pub enum Type {
5    Address,
6    FixedBytes(usize),
7    Bytes,
8    Int(usize),
9    Uint(usize),
10    Bool,
11    String,
12    FixedArray(Box<Type>, usize),
13    Array(Box<Type>),
14    Tuple(Vec<Type>),
15}
16
17pub type SchemaPart = Vec<(String, Type)>;
18
19pub struct Schema {
20    parts: SchemaPart,
21}
22
23pub struct SchemaBuilder {
24    parts: SchemaPart,
25}
26
27impl Default for SchemaBuilder {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl SchemaBuilder {
34    pub fn new() -> Self {
35        SchemaBuilder { parts: vec![] }
36    }
37
38    pub fn add(mut self, name: &str, token_type: Type) -> Self {
39        self.parts.push((name.to_owned(), token_type));
40        self
41    }
42
43    pub fn build(self) -> Schema {
44        Schema { parts: self.parts }
45    }
46}
47
48fn token_type_to_abi_type(token_type: &Type) -> String {
49    match token_type {
50        Type::Address => "address".into(),
51        Type::FixedBytes(size) => format!("bytes{}", size),
52        Type::Bytes => "bytes".into(),
53        Type::Int(size) => format!("int{}", size),
54        Type::Uint(size) => format!("uint{}", size),
55        Type::Bool => "bool".into(),
56        Type::String => "string".into(),
57        Type::FixedArray(token_type, size) => {
58            format!("{}[{}]", token_type_to_abi_type(token_type), size)
59        }
60        Type::Array(token_type) => {
61            format!("{}[]", token_type_to_abi_type(token_type))
62        }
63        Type::Tuple(types) => {
64            let inner_types = types
65                .iter()
66                .map(token_type_to_abi_type)
67                .collect::<Vec<String>>()
68                .join(",");
69            format!("({})", inner_types)
70        }
71    }
72}
73
74impl Display for Schema {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        let parts = self
77            .parts
78            .iter()
79            .map(|(name, token_type)| format!("{} {}", token_type_to_abi_type(token_type), name))
80            .collect::<Vec<String>>()
81            .join(", ");
82        write!(f, "{}", parts)
83    }
84}
85
86impl From<Schema> for String {
87    fn from(schema: Schema) -> Self {
88        schema.to_string()
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use crate::schema::{SchemaBuilder, Type};
95
96    #[test]
97    fn schema_test() {
98        let schema = SchemaBuilder::new()
99            .add("name", Type::String)
100            .add("age", Type::Uint(8))
101            .add("address", Type::Address)
102            .add("data", Type::FixedArray(Box::new(Type::Uint(8)), 3))
103            .add("data2", Type::Array(Box::new(Type::Uint(8))))
104            .add("data3", Type::Tuple(vec![Type::Uint(8), Type::Uint(8)]))
105            .build();
106        assert_eq!(schema.to_string(), "string name, uint8 age, address address, uint8[3] data, uint8[] data2, (uint8,uint8) data3");
107    }
108}