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::{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}