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}