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