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}