Skip to main content

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