1use crate::prelude::*;
4use casper_event_standard::EventInstance;
5use casper_types::{
6 bytesrepr::{FromBytes, ToBytes},
7 CLType, Key, PublicKey, URef, U128, U256, U512
8};
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Entrypoint {
14 pub name: String,
16 pub args: Vec<Argument>,
18 pub is_mutable: bool,
20 pub return_ty: CLType,
22 pub ty: EntrypointType,
24 pub attributes: Vec<EntrypointAttribute>
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
30pub struct Argument {
31 pub name: String,
33 pub ty: CLType,
35 pub is_ref: bool,
37 pub is_slice: bool,
39 pub is_required: bool
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
45pub struct Event {
46 pub name: String,
48 pub args: Vec<Argument>
50}
51
52impl Event {
53 pub fn has_any(&self) -> bool {
55 self.args.iter().any(|arg| arg.ty == CLType::Any)
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
61pub enum EntrypointType {
62 Constructor,
64 Public
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
70pub enum EntrypointAttribute {
71 NonReentrant,
73 Payable
75}
76
77pub trait HasIdent {
79 fn ident() -> String;
81}
82
83pub trait HasEntrypoints {
86 fn entrypoints() -> Vec<Entrypoint>;
88}
89
90pub trait HasEvents {
92 fn events() -> Vec<Event>;
94
95 fn event_schemas() -> crate::prelude::BTreeMap<String, casper_event_standard::Schema> {
97 crate::prelude::BTreeMap::new()
98 }
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct ContractBlueprint {
107 pub name: String,
109 pub events: Vec<Event>,
111 pub entrypoints: Vec<Entrypoint>
113}
114
115impl ContractBlueprint {
116 pub fn new<T: HasIdent + HasEvents + HasEntrypoints>() -> Self {
127 Self {
128 name: T::ident(),
129 events: T::events(),
130 entrypoints: T::entrypoints()
131 }
132 }
133
134 pub fn as_json(self) -> Result<String, serde_json::Error> {
141 serde_json::to_string_pretty(&self)
142 }
143}
144
145pub trait IntoEvent {
147 fn into_event() -> Event;
149}
150
151impl<T: EventInstance> IntoEvent for T {
152 fn into_event() -> Event {
153 let mut schemas = casper_event_standard::Schemas::new();
154 schemas.add::<T>();
155 let name = <T as EventInstance>::name();
156 let schema = <T as EventInstance>::schema();
157 let args = schema
158 .to_vec()
159 .iter()
160 .map(|(name, ty)| Argument {
161 name: name.clone(),
162 ty: ty.clone().downcast(),
163 is_ref: false,
164 is_slice: false,
165 is_required: true
166 })
167 .collect::<Vec<_>>();
168 Event { name, args }
169 }
170}
171
172macro_rules! impl_has_events {
173 ($($t:ty),*) => {
174 impl HasEvents for () {
175 fn events() -> Vec<Event> {
176 vec![]
177 }
178 }
179
180 $(
181 impl HasEvents for $t {
182 fn events() -> Vec<Event> {
183 vec![]
184 }
185 }
186 )*
187 };
188}
189
190impl_has_events!(
191 u8, u16, u32, u64, i8, i16, i32, i64, U128, U256, U512, Address, String, bool, Key, URef,
192 PublicKey
193);
194
195impl<T: ToBytes + FromBytes, const N: usize> HasEvents for [T; N] {
196 fn events() -> Vec<Event> {
197 vec![]
198 }
199}
200
201impl<T: ToBytes + FromBytes> HasEvents for Option<T> {
202 fn events() -> Vec<Event> {
203 vec![]
204 }
205}
206
207impl<T: ToBytes + FromBytes, E: ToBytes + FromBytes> HasEvents for Result<T, E> {
208 fn events() -> Vec<Event> {
209 vec![]
210 }
211}
212
213impl<T: ToBytes + FromBytes, E: ToBytes + FromBytes> HasEvents for BTreeMap<T, E> {
214 fn events() -> Vec<Event> {
215 vec![]
216 }
217}
218
219impl<T: ToBytes + FromBytes> HasEvents for Vec<T> {
220 fn events() -> Vec<Event> {
221 vec![]
222 }
223}
224
225impl<T1: ToBytes + FromBytes> HasEvents for (T1,) {
226 fn events() -> Vec<Event> {
227 vec![]
228 }
229}
230
231impl<T1: ToBytes + FromBytes, T2: ToBytes + FromBytes> HasEvents for (T1, T2) {
232 fn events() -> Vec<Event> {
233 vec![]
234 }
235}
236
237impl<T1: ToBytes + FromBytes, T2: ToBytes + FromBytes, T3: ToBytes + FromBytes> HasEvents
238 for (T1, T2, T3)
239{
240 fn events() -> Vec<Event> {
241 vec![]
242 }
243}