telchar_codegen/
schema.rs

1//! This module defines the structures and implementations for schemas, including types, references, and validators.
2
3use std::str;
4use serde::{Deserialize, Serialize};
5
6/// Represents the different types a schema can have.
7#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
8pub enum TypeName {
9    AnyData,
10    Integer,
11    Bytes,
12    Literal,
13    Nullable,
14    Object,
15    Enum,
16    Tuple,
17    List,
18}
19
20/// Represents a schema with a name, type, optional properties, and JSON representation.
21#[derive(Debug, Deserialize, Serialize, Clone)]
22pub struct Schema {
23    pub name: String,
24    pub type_name: TypeName,
25    pub properties: Option<Vec<Reference>>,
26    pub json: String,
27}
28
29/// Represents a reference to another schema, including an optional name and schema name.
30#[derive(Debug, Deserialize, Serialize, Clone)]
31pub struct Reference {
32    pub name: Option<String>,
33    pub schema_name: String,
34}
35
36/// Represents a validator with a name, optional datum and redeemer, and parameters.
37#[derive(Debug, Deserialize, Serialize, Clone)]
38pub struct Validator {
39    pub name: String,
40    pub datum: Option<Reference>,
41    pub redeemer: Option<Reference>,
42    pub parameters: Vec<Reference>,
43}
44
45impl Schema {
46    /// Creates a new any data schema.
47    ///
48    /// # Arguments
49    ///
50    /// * `json` - The JSON representation of the schema.
51    ///
52    /// # Returns
53    ///
54    /// A new `Schema` instance with type `AnyData`.
55    pub fn new_anydata(json: String) -> Self {
56        Self { name: "AnyData".to_string(), type_name: TypeName::AnyData, properties: None, json }
57    }
58
59    /// Creates a new integer schema.
60    ///
61    /// # Arguments
62    ///
63    /// * `name` - The name of the schema.
64    /// * `json` - The JSON representation of the schema.
65    ///
66    /// # Returns
67    ///
68    /// A new `Schema` instance with type `Integer`.
69    pub fn new_integer(name: String, json: String) -> Self {
70        Self { name, type_name: TypeName::Integer, properties: None, json }
71    }
72
73    /// Creates a new bytes schema.
74    ///
75    /// # Arguments
76    ///
77    /// * `name` - The name of the schema.
78    /// * `json` - The JSON representation of the schema.
79    ///
80    /// # Returns
81    ///
82    /// A new `Schema` instance with type `Bytes`.
83    pub fn new_bytes(name: String, json: String) -> Self {
84        Self { name, type_name: TypeName::Bytes, properties: None, json }
85    }
86
87    /// Creates a new literal schema.
88    ///
89    /// # Arguments
90    ///
91    /// * `name` - The name of the schema.
92    /// * `value` - The literal value of the schema.
93    /// * `json` - The JSON representation of the schema.
94    ///
95    /// # Returns
96    ///
97    /// A new `Schema` instance with type `Literal`.
98    pub fn new_literal(name: String, value: String, json: String) -> Self {
99        Self { name, type_name: TypeName::Literal, properties: Some(vec![Reference{ name: None, schema_name: value }]), json }
100    }
101
102    /// Creates a new nullable schema.
103    ///
104    /// # Arguments
105    ///
106    /// * `name` - The name of the schema.
107    /// * `reference` - The reference schema name.
108    /// * `json` - The JSON representation of the schema.
109    ///
110    /// # Returns
111    ///
112    /// A new `Schema` instance with type `Nullable`.
113    pub fn new_nullable(name: String, reference: String, json: String) -> Self {
114        Self { name, type_name: TypeName::Nullable, properties: Some(vec![Reference{ name: None, schema_name: reference }]), json }
115    }
116
117    /// Creates a new object schema.
118    ///
119    /// # Arguments
120    ///
121    /// * `name` - The name of the schema.
122    /// * `properties` - The properties of the object schema.
123    /// * `json` - The JSON representation of the schema.
124    ///
125    /// # Returns
126    ///
127    /// A new `Schema` instance with type `Object`.
128    pub fn new_object(name: String, properties: Vec<Reference>, json: String) -> Self {
129        Self { name, type_name: TypeName::Object, properties: Some(properties), json }
130    }
131
132    /// Creates a new enum schema.
133    ///
134    /// # Arguments
135    ///
136    /// * `name` - The name of the schema.
137    /// * `schemas` - The schemas that make up the enum.
138    /// * `json` - The JSON representation of the schema.
139    ///
140    /// # Returns
141    ///
142    /// A new `Schema` instance with type `Enum`.
143    pub fn new_enum(name: String, schemas: &Vec<Schema>, json: String) -> Self {
144        Self {
145            name, type_name: TypeName::Enum,
146            properties: Some(schemas.iter().map(|s|
147                Reference{ name: None, schema_name: s.name.clone() }
148            ).collect()),
149            json
150        }
151    }
152
153    /// Creates a new tuple schema.
154    ///
155    /// # Arguments
156    ///
157    /// * `name` - The name of the schema.
158    /// * `properties` - The properties of the tuple schema.
159    /// * `json` - The JSON representation of the schema.
160    ///
161    /// # Returns
162    ///
163    /// A new `Schema` instance with type `Tuple`.
164    pub fn new_tuple(name: String, properties: Vec<Reference>, json: String) -> Self {
165        Self { name, type_name: TypeName::Tuple, properties: Some(properties), json }
166    }
167
168    /// Creates a new list schema.
169    ///
170    /// # Arguments
171    ///
172    /// * `name` - The name of the schema.
173    /// * `reference` - The reference schema.
174    /// * `json` - The JSON representation of the schema.
175    ///
176    /// # Returns
177    ///
178    /// A new `Schema` instance with type `List`.
179    pub fn new_list(name: String, reference: Reference, json: String) -> Self {
180        Self { name, type_name: TypeName::List, properties: Some(vec![reference]), json }
181    }
182}
183
184impl str::FromStr for TypeName {
185    type Err = ();
186
187    /// Converts a string to a `TypeName`.
188    ///
189    /// # Arguments
190    ///
191    /// * `input` - The string representation of the type name.
192    ///
193    /// # Returns
194    ///
195    /// A `Result` containing the `TypeName` or an error.
196    fn from_str(input: &str) -> Result<TypeName, Self::Err> {
197        match input {
198            "AnyData" => Ok(TypeName::AnyData),
199            "Integer" => Ok(TypeName::Integer),
200            "Bytes" => Ok(TypeName::Bytes),
201            "Literal" => Ok(TypeName::Literal),
202            "Nullable" => Ok(TypeName::Nullable),
203            "Object" => Ok(TypeName::Object),
204            "Enum" => Ok(TypeName::Enum),
205            "Tuple" => Ok(TypeName::Tuple),
206            "List" => Ok(TypeName::List),
207            _ => Err(()),
208        }
209    }
210}