1use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6mod ty;
7pub use ty::NamedCLType;
8
9#[derive(Serialize, Deserialize, JsonSchema, Debug)]
11pub struct ContractSchema {
12 pub casper_contract_schema_version: u8,
13 pub toolchain: String,
14 pub authors: Vec<String>,
15 pub repository: Option<String>,
16 pub homepage: Option<String>,
17 pub contract_name: String,
18 pub contract_version: String,
19 pub types: Vec<CustomType>,
20 pub errors: Vec<UserError>,
21 pub entry_points: Vec<Entrypoint>,
22 pub events: Vec<Event>,
23 pub call: Option<CallMethod>,
24}
25
26impl ContractSchema {
27 pub fn as_json(&self) -> Option<String> {
29 serde_json::to_string_pretty(self).ok()
30 }
31}
32
33#[derive(Serialize, Deserialize, JsonSchema, Debug)]
35pub struct Entrypoint {
36 pub name: String,
37 pub description: Option<String>,
38 pub is_mutable: bool,
39 pub arguments: Vec<Argument>,
40 pub return_ty: Type,
41 pub is_contract_context: bool,
42 pub access: Access,
43}
44
45#[derive(Clone, Serialize, Deserialize, JsonSchema, Debug)]
47pub struct Argument {
48 pub name: String,
49 pub description: Option<String>,
50 pub ty: Type,
51 pub optional: bool,
52}
53
54impl Argument {
55 pub fn new(name: &str, description: &str, ty: NamedCLType) -> Self {
56 Self {
57 name: String::from(name),
58 description: parse_description(description),
59 ty: ty.into(),
60 optional: false,
61 }
62 }
63
64 pub fn new_opt(name: &str, description: &str, ty: NamedCLType) -> Self {
65 Self {
66 name: String::from(name),
67 description: parse_description(description),
68 ty: ty.into(),
69 optional: true,
70 }
71 }
72}
73
74#[derive(Serialize, Deserialize, JsonSchema, Debug)]
76#[serde(rename_all = "snake_case")]
77pub enum Access {
78 Public,
79 Groups(Vec<String>),
80}
81
82#[derive(PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize, JsonSchema, Debug)]
84pub struct StructMember {
85 pub name: String,
86 pub description: Option<String>,
87 pub ty: Type,
88}
89
90impl StructMember {
91 pub fn new(name: &str, description: &str, ty: NamedCLType) -> Self {
93 Self {
94 name: String::from(name),
95 description: parse_description(description),
96 ty: ty.into(),
97 }
98 }
99}
100
101fn parse_description(description: &str) -> Option<String> {
102 if description.is_empty() {
103 None
104 } else {
105 Some(String::from(description))
106 }
107}
108
109#[derive(PartialEq, PartialOrd, Ord, Eq, Clone, Serialize, Deserialize, JsonSchema, Debug)]
111#[serde(rename_all = "snake_case")]
112pub struct Type(pub NamedCLType);
113
114impl From<NamedCLType> for Type {
115 fn from(cl_type: NamedCLType) -> Self {
116 Self(cl_type)
117 }
118}
119
120#[derive(PartialEq, PartialOrd, Ord, Eq, Clone, Serialize, Deserialize, JsonSchema, Debug)]
122pub struct TypeName(pub String);
123
124impl From<&str> for TypeName {
125 fn from(name: &str) -> Self {
126 Self(String::from(name))
127 }
128}
129
130impl From<String> for TypeName {
131 fn from(name: String) -> Self {
132 Self(name)
133 }
134}
135
136impl TypeName {
137 pub fn new(name: &str) -> Self {
139 Self(String::from(name))
140 }
141}
142
143#[derive(PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize, JsonSchema, Debug)]
145#[serde(rename_all = "snake_case")]
146pub enum CustomType {
147 Struct {
148 name: TypeName,
149 description: Option<String>,
150 members: Vec<StructMember>,
151 },
152 Enum {
153 name: TypeName,
154 description: Option<String>,
155 variants: Vec<EnumVariant>,
156 },
157}
158
159#[derive(PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize, JsonSchema, Debug)]
161pub struct EnumVariant {
162 pub name: String,
163 pub description: Option<String>,
164 pub discriminant: u16,
165 pub ty: Type,
166}
167
168#[derive(PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize, JsonSchema, Debug)]
170pub struct Event {
171 pub name: String,
172 pub ty: TypeName,
173}
174
175impl Event {
176 pub fn new(name: &str, ty: &str) -> Self {
178 Self {
179 name: String::from(name),
180 ty: ty.into(),
181 }
182 }
183}
184
185#[derive(PartialEq, PartialOrd, Ord, Eq, Serialize, Deserialize, JsonSchema, Debug)]
187pub struct UserError {
188 pub name: String,
189 pub description: Option<String>,
190 pub discriminant: u16,
191}
192
193impl UserError {
194 pub fn new(name: &str, desc: &str, discriminant: u16) -> Self {
196 Self {
197 name: String::from(name),
198 description: parse_description(desc),
199 discriminant,
200 }
201 }
202}
203
204#[derive(Serialize, Deserialize, JsonSchema, Debug)]
206pub struct CallMethod {
207 pub wasm_file_name: String,
208 pub description: Option<String>,
209 pub arguments: Vec<Argument>,
210}
211
212impl CallMethod {
213 pub fn new(wasm_file_name: &str, description: &str, arguments: Vec<Argument>) -> Self {
215 Self {
216 wasm_file_name: String::from(wasm_file_name),
217 description: parse_description(description),
218 arguments,
219 }
220 }
221}