dusk_forge/schema.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7//! Schema types for contract metadata.
8//!
9//! These types are used by the `#[contract]` macro to generate
10//! compile-time contract schemas that describe functions and events.
11
12extern crate alloc;
13
14use serde::Serialize;
15
16/// Schema for a contract function.
17#[derive(Debug, Clone, Copy, Serialize)]
18pub struct Function {
19 /// Function name.
20 pub name: &'static str,
21 /// Documentation string.
22 pub doc: &'static str,
23 /// Input type name (or "()" for no input).
24 pub input: &'static str,
25 /// Output type name (or "()" for no output).
26 pub output: &'static str,
27}
28
29/// Schema for a contract event.
30#[derive(Debug, Clone, Copy, Serialize)]
31pub struct Event {
32 /// Topics under which the event is emitted.
33 pub topics: &'static [&'static str],
34 /// Event data type name.
35 pub data: &'static str,
36}
37
38/// Schema for an imported type.
39#[derive(Debug, Clone, Copy, Serialize)]
40pub struct Import {
41 /// The short name used in the contract (e.g., `SetU64`).
42 pub name: &'static str,
43 /// The full path to the type (e.g., `my_crate::MyType`).
44 pub path: &'static str,
45}
46
47/// Complete schema for a contract.
48#[derive(Debug, Clone, Copy, Serialize)]
49pub struct Contract {
50 /// Contract name.
51 pub name: &'static str,
52 /// List of imported types with their full paths.
53 pub imports: &'static [Import],
54 /// List of contract functions.
55 pub functions: &'static [Function],
56 /// List of contract events.
57 pub events: &'static [Event],
58}
59
60impl Contract {
61 /// Returns an iterator over all imports.
62 pub fn iter_imports(&self) -> impl Iterator<Item = &Import> {
63 self.imports.iter()
64 }
65
66 /// Returns an iterator over all functions.
67 pub fn iter_functions(&self) -> impl Iterator<Item = &Function> {
68 self.functions.iter()
69 }
70
71 /// Returns an iterator over all events.
72 pub fn iter_events(&self) -> impl Iterator<Item = &Event> {
73 self.events.iter()
74 }
75
76 /// Find an import by short name.
77 #[must_use]
78 pub fn get_import(&self, name: &str) -> Option<&Import> {
79 self.imports.iter().find(|i| i.name == name)
80 }
81
82 /// Find a function by name.
83 #[must_use]
84 pub fn get_function(&self, name: &str) -> Option<&Function> {
85 self.functions.iter().find(|f| f.name == name)
86 }
87
88 /// Find an event by topic.
89 #[must_use]
90 pub fn get_event(&self, topic: &str) -> Option<&Event> {
91 self.events.iter().find(|e| e.topics.contains(&topic))
92 }
93
94 /// Serialize the schema to a JSON string.
95 #[must_use]
96 pub fn to_json(&self) -> alloc::string::String {
97 serde_json::to_string(self).unwrap_or_else(|_| alloc::string::String::from("{}"))
98 }
99}