dusk_data_driver/lib.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//! Types used for interacting with Dusk's transfer and stake contracts.
8
9#![cfg_attr(not(feature = "reader"), no_std)]
10#![deny(missing_docs)]
11#![deny(rustdoc::broken_intra_doc_links)]
12#![deny(clippy::pedantic)]
13#![allow(clippy::module_name_repetitions)]
14#![cfg_attr(not(test), deny(unused_crate_dependencies))]
15#![deny(unused_extern_crates)]
16
17extern crate alloc;
18
19#[cfg(feature = "reader")]
20extern crate std;
21
22mod error;
23
24#[cfg(all(target_family = "wasm", feature = "wasm-export"))]
25pub mod wasm;
26
27#[cfg(all(target_family = "wasm", feature = "alloc"))]
28mod mem;
29
30#[cfg(feature = "reader")]
31pub mod reader;
32
33use alloc::string::{String, ToString};
34use alloc::vec::Vec;
35use alloc::{format, vec};
36
37use bytecheck::CheckBytes;
38pub use error::Error;
39use rkyv::validation::validators::DefaultValidator;
40use rkyv::{Archive, Deserialize, Infallible, check_archived_root};
41pub use serde_json::{Value as JsonValue, to_value as to_json};
42
43/// A trait for converting between JSON and native RKYV formats in a contract.
44///
45/// The `ConvertibleContract` trait provides methods for encoding and decoding
46/// function inputs, outputs, and events, as well as retrieving the contract's
47/// JSON schema.
48pub trait ConvertibleContract: Send {
49 /// Encodes the input of a function from JSON into the native RKYV format.
50 ///
51 /// # Parameters
52 /// - `fn_name`: The name of the function whose input is being encoded.
53 /// - `json`: A JSON string representing the function's input.
54 ///
55 /// # Returns
56 /// - `Ok(Vec<u8>)`: A byte vector containing the serialized RKYV data.
57 /// - `Err(Error)`: If encoding fails.
58 ///
59 /// # Errors
60 /// - Returns `Error::Rkyv` if the serialization process fails.
61 /// - Returns `Error::Serde` if the input JSON cannot be parsed.
62 fn encode_input_fn(
63 &self,
64 fn_name: &str,
65 json: &str,
66 ) -> Result<Vec<u8>, Error>;
67
68 /// Decodes the input of a function from the native RKYV format into JSON.
69 ///
70 /// # Parameters
71 /// - `fn_name`: The name of the function whose input is being decoded.
72 /// - `rkyv`: A byte slice containing the RKYV-encoded function input.
73 ///
74 /// # Returns
75 /// - `Ok(JsonValue)`: A JSON representation of the function input.
76 /// - `Err(Error)`: If decoding fails.
77 ///
78 /// # Errors
79 /// - Returns `Error::Rkyv` if the deserialization process fails.
80 /// - Returns `Error::Serde` if the resulting object cannot be serialized to
81 /// JSON.
82 fn decode_input_fn(
83 &self,
84 fn_name: &str,
85 rkyv: &[u8],
86 ) -> Result<JsonValue, Error>;
87
88 /// Decodes the output of a function from the native RKYV format into JSON.
89 ///
90 /// # Parameters
91 /// - `fn_name`: The name of the function whose output is being decoded.
92 /// - `rkyv`: A byte slice containing the RKYV-encoded function output.
93 ///
94 /// # Returns
95 /// - `Ok(JsonValue)`: A JSON representation of the function output.
96 /// - `Err(Error)`: If decoding fails.
97 ///
98 /// # Errors
99 /// - Returns `Error::Rkyv` if the deserialization process fails.
100 /// - Returns `Error::Serde` if the resulting object cannot be serialized to
101 /// JSON.
102 fn decode_output_fn(
103 &self,
104 fn_name: &str,
105 rkyv: &[u8],
106 ) -> Result<JsonValue, Error>;
107
108 /// Decodes an event from the native RKYV format into JSON.
109 ///
110 /// # Parameters
111 /// - `event_name`: The name of the event to be decoded.
112 /// - `rkyv`: A byte slice containing the RKYV-encoded event data.
113 ///
114 /// # Returns
115 /// - `Ok(JsonValue)`: A JSON representation of the event data.
116 /// - `Err(Error)`: If decoding fails.
117 ///
118 /// # Errors
119 /// - Returns `Error::Rkyv` if the deserialization process fails.
120 /// - Returns `Error::Serde` if the resulting object cannot be serialized to
121 /// JSON.
122 fn decode_event(
123 &self,
124 event_name: &str,
125 rkyv: &[u8],
126 ) -> Result<JsonValue, Error>;
127
128 /// Returns the JSON schema describing the contract's data structure.
129 ///
130 /// # Returns
131 /// - `String`: A JSON string containing the contract's schema definition.
132 ///
133 /// # Errors
134 /// - This function does not return an error.
135 fn get_schema(&self) -> String;
136
137 /// Returns the current version of the contract interface.
138 ///
139 /// This is useful for ensuring compatibility between different contract
140 /// consumers and implementations.
141 ///
142 /// # Returns
143 /// - `&'static str`: A string representing the semantic version (e.g.,
144 /// `"0.10.1"`).
145 #[must_use]
146 fn get_version(&self) -> &'static str {
147 "0.1.0"
148 }
149}
150
151/// Converts a JSON string into a serialized RKYV archive.
152///
153/// # Parameters
154/// - `json`: A JSON string representing the object to be serialized.
155///
156/// # Returns
157/// - `Ok(Vec<u8>)`: A byte vector containing the serialized RKYV data.
158/// - `Err(Error)`: If serialization fails.
159///
160/// # Type Parameters
161/// - `I`: The type of the object being serialized. Must implement:
162/// - `serde::de::Deserialize<'a>`: Allows deserialization from JSON.
163/// - `rkyv::Archive`: Indicates the type is archivable.
164/// - `rkyv::Serialize<rkyv::ser::serializers::AllocSerializer<1024>>`:
165/// Enables RKYV serialization.
166///
167/// # Errors
168/// - Returns `serde_json::Error` if JSON deserialization fails.
169/// - Returns `Error::Rkyv` if RKYV serialization fails.
170pub fn json_to_rkyv<'a, I>(json: &'a str) -> Result<Vec<u8>, Error>
171where
172 I: serde::de::Deserialize<'a>,
173 I: Archive,
174 I: rkyv::Serialize<rkyv::ser::serializers::AllocSerializer<1024>>,
175{
176 let object: I = serde_json::from_str(json)?;
177 let rkyv = rkyv::to_bytes(&object)
178 .map_err(|e| Error::Rkyv(format!("cannot serialize: {e}")))?
179 .to_vec();
180
181 Ok(rkyv)
182}
183
184/// Converts a serialized RKYV archive into a JSON object.
185///
186/// # Parameters
187/// - `rkyv`: A byte slice containing the serialized RKYV data.
188///
189/// # Returns
190/// - `Ok(JsonValue)`: A JSON representation of the deserialized object.
191/// - `Err(Error)`: If deserialization fails.
192///
193/// # Type Parameters
194/// - `T`: The type of the object being deserialized. Must implement:
195/// - `serde::ser::Serialize`: Required for JSON conversion.
196/// - `rkyv::Archive`: Indicates the type is archivable.
197/// - `CheckBytes<DefaultValidator<'a>>`: Ensures safety of archived data.
198/// - `Deserialize<T, Infallible>`: Allows deserialization into `T`.
199///
200/// # Errors
201/// - Returns `Error::Rkyv` if:
202/// - The archive cannot be validated (`check_archived_root` fails).
203/// - Deserialization from RKYV to Rust fails.
204/// - Returns `serde_json::Error` if JSON serialization fails.
205pub fn rkyv_to_json<T>(rkyv: &[u8]) -> Result<serde_json::Value, Error>
206where
207 T: serde::ser::Serialize,
208 T: Archive,
209 for<'a> T::Archived:
210 CheckBytes<DefaultValidator<'a>> + Deserialize<T, Infallible>,
211{
212 let object: T = from_rkyv(rkyv)?;
213 let json = serde_json::to_value(&object)?;
214
215 Ok(json)
216}
217
218/// Converts a serialized RKYV archive into a T.
219///
220/// # Parameters
221/// - `rkyv`: A byte slice containing the serialized RKYV data.
222///
223/// # Returns
224/// - `Ok(T)`: The deserialized object
225/// - `Err(Error)`: If deserialization fails.
226///
227/// # Type Parameters
228/// - `T`: The type of the object being deserialized. Must implement:
229/// - `rkyv::Archive`: Indicates the type is archivable.
230/// - `CheckBytes<DefaultValidator<'a>>`: Ensures safety of archived data.
231/// - `Deserialize<T, Infallible>`: Allows deserialization into `T`.
232///
233/// # Errors
234/// - Returns `Error::Rkyv` if:
235/// - The archive cannot be validated (`check_archived_root` fails).
236/// - Deserialization from RKYV to Rust fails.
237pub fn from_rkyv<T>(rkyv: &[u8]) -> Result<T, Error>
238where
239 T: Archive,
240 for<'a> T::Archived:
241 CheckBytes<DefaultValidator<'a>> + Deserialize<T, Infallible>,
242{
243 let root = check_archived_root::<T>(rkyv)
244 .map_err(|e| Error::Rkyv(format!("cannot check_archived_root: {e}")))?;
245 let object: T = root
246 .deserialize(&mut Infallible)
247 .map_err(|e| Error::Rkyv(format!("cannot deserialize: {e}")))?;
248
249 Ok(object)
250}
251
252/// Converts a JSON string into a serialized RKYV archive of a `u64` value.
253///
254/// # Parameters
255/// - `json`: A JSON string representing a `u64` value.
256///
257/// # Returns
258/// - `Ok(Vec<u8>)`: A byte vector containing the serialized RKYV data.
259/// - `Err(Error)`: If serialization fails.
260///
261/// # Errors
262/// - Returns `serde_json::Error` if JSON deserialization fails.
263/// - Returns `Error::Rkyv` if RKYV serialization fails.
264pub fn json_to_rkyv_u64(json: &str) -> Result<Vec<u8>, Error> {
265 let json = json.replace('"', "");
266 json_to_rkyv::<u64>(&json)
267}
268
269/// Converts a serialized RKYV archive into a JSON string representing a `u64`
270/// value.
271///
272/// # Parameters
273/// - `rkyv`: A byte slice containing the serialized RKYV data.
274///
275/// # Returns
276/// - `Ok(JsonValue)`: A JSON string representation of the deserialized `u64`
277/// value.
278/// - `Err(Error)`: If deserialization fails.
279///
280/// # Errors
281/// - Returns `Error::Rkyv` if deserialization from RKYV to `u64` fails.
282/// - Returns `serde_json::Error` if JSON serialization fails.
283pub fn rkyv_to_json_u64(rkyv: &[u8]) -> Result<JsonValue, Error> {
284 from_rkyv::<u64>(rkyv).map(|v| JsonValue::String(v.to_string()))
285}
286
287/// Converts a JSON string into a serialized RKYV archive of a tuple `(u64,
288/// u64)`.
289///
290/// # Parameters
291/// - `json`: A JSON string representing a 2-tuple of `u64` values.
292///
293/// # Returns
294/// - `Ok(Vec<u8>)`: A byte vector containing the serialized RKYV data.
295/// - `Err(Error)`: If serialization fails.
296///
297/// # Errors
298/// - Returns `serde_json::Error` if JSON deserialization fails.
299/// - Returns `Error::Rkyv` if RKYV serialization fails.
300pub fn json_to_rkyv_pair_u64(json: &str) -> Result<Vec<u8>, Error> {
301 let json = json.replace('"', "");
302 json_to_rkyv::<(u64, u64)>(&json)
303}
304
305/// Converts a serialized RKYV archive into a JSON array of two `u64` values.
306///
307/// # Parameters
308/// - `rkyv`: A byte slice containing the serialized RKYV data.
309///
310/// # Returns
311/// - `Ok(JsonValue)`: A JSON array containing the two `u64` values as strings.
312/// - `Err(Error)`: If deserialization fails.
313///
314/// # Errors
315/// - Returns `Error::Rkyv` if deserialization from RKYV to `(u64, u64)` fails.
316/// - Returns `Error::Rkyv` if the deserialized data is not an array.
317/// - Returns `serde_json::Error` if JSON serialization fails.
318pub fn rkyv_to_json_pair_u64(rkyv: &[u8]) -> Result<JsonValue, Error> {
319 let json_array = from_rkyv::<(u64, u64)>(rkyv).map(|(v1, v2)| {
320 JsonValue::Array(vec![
321 JsonValue::String(v1.to_string()),
322 JsonValue::String(v2.to_string()),
323 ])
324 })?;
325 Ok(json_array)
326}