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