Skip to content

Commit dcd2cc3

Browse files
committed
add Json instances
1 parent 529778d commit dcd2cc3

File tree

6 files changed

+145
-12
lines changed

6 files changed

+145
-12
lines changed

src/generators/correct/v1.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,11 @@ pub fn arb_assoc_map<K: std::fmt::Debug, V: std::fmt::Debug>(
304304
vec((arb_k, arb_v), 10).prop_map(AssocMap)
305305
}
306306

307-
pub fn arb_tuple<K: std::fmt::Debug, V: std::fmt::Debug>(
308-
arb_k: impl Strategy<Value = K>,
309-
arb_v: impl Strategy<Value = V>,
310-
) -> impl Strategy<Value = Tuple<K, V>> {
311-
(arb_k, arb_v).prop_map(Tuple)
307+
pub fn arb_tuple<T: std::fmt::Debug, U: std::fmt::Debug>(
308+
arb_k: impl Strategy<Value = T>,
309+
arb_v: impl Strategy<Value = U>,
310+
) -> impl Strategy<Value = Tuple<T, U>> {
311+
(arb_k, arb_v).prop_map(|(l, r)| Tuple(l, r))
312312
}
313313

314314
pub fn arb_payment_pub_key_hash() -> impl Strategy<Value = PaymentPubKeyHash> {

src/v1/assoc_map.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
use std::hash::Hash;
22

3+
#[cfg(feature = "lbf")]
4+
use lbr_prelude::json::{json_array, Json};
35
use linked_hash_map::LinkedHashMap;
6+
#[cfg(feature = "serde")]
7+
use serde::{Deserialize, Serialize};
48

59
use crate::plutus_data::{IsPlutusData, PlutusData, PlutusDataError, PlutusType};
610

711
use super::tuple::Tuple;
812

913
#[derive(Debug, PartialEq, Eq, Clone)]
14+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1015
pub struct AssocMap<K, V>(pub Vec<(K, V)>);
1116

1217
impl<K: IsPlutusData, V: IsPlutusData> IsPlutusData for AssocMap<K, V> {
@@ -36,13 +41,13 @@ impl<K: IsPlutusData, V: IsPlutusData> IsPlutusData for AssocMap<K, V> {
3641

3742
impl<K, V> From<Vec<Tuple<K, V>>> for AssocMap<K, V> {
3843
fn from(vec: Vec<Tuple<K, V>>) -> Self {
39-
AssocMap(vec.into_iter().map(|t| t.0).collect())
44+
AssocMap(vec.into_iter().map(|Tuple(l, r)| (l, r)).collect())
4045
}
4146
}
4247

4348
impl<K, V> From<AssocMap<K, V>> for Vec<Tuple<K, V>> {
4449
fn from(m: AssocMap<K, V>) -> Self {
45-
m.0.into_iter().map(Tuple).collect()
50+
m.0.into_iter().map(|(l, r)| Tuple(l, r)).collect()
4651
}
4752
}
4853

@@ -57,3 +62,39 @@ impl<K: Hash + Eq, V> From<LinkedHashMap<K, V>> for AssocMap<K, V> {
5762
AssocMap(value.into_iter().collect())
5863
}
5964
}
65+
66+
#[cfg(feature = "lbf")]
67+
impl<K: Json, V: Json> Json for AssocMap<K, V> {
68+
fn to_json(&self) -> serde_json::Value {
69+
json_array(
70+
(&self.0)
71+
.into_iter()
72+
.map(|(k, v)| json_array(vec![k.to_json(), v.to_json()]))
73+
.collect(),
74+
)
75+
}
76+
77+
fn from_json(value: &serde_json::Value) -> Result<Self, lbr_prelude::json::Error> {
78+
let vec_of_vectors: Vec<Vec<serde_json::Value>> = Json::from_json(value)?;
79+
let vec_of_pairs = vec_of_vectors
80+
.into_iter()
81+
.map(|vec| {
82+
let [k, v]: [serde_json::Value; 2] =
83+
TryFrom::try_from(vec).map_err(|vec: Vec<_>| {
84+
lbr_prelude::json::Error::UnexpectedArrayLength {
85+
got: vec.len(),
86+
wanted: 2,
87+
parser: "v1::assoc_map::AssocMap".into(),
88+
}
89+
})?;
90+
91+
let k = K::from_json(&k)?;
92+
let v = V::from_json(&v)?;
93+
94+
Ok((k, v))
95+
})
96+
.collect::<Result<Vec<(K, V)>, _>>()?;
97+
98+
Ok(Self(vec_of_pairs))
99+
}
100+
}

src/v1/transaction.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ impl IsPlutusData for TxInInfo {
216216
}
217217

218218
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
219+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
220+
#[cfg_attr(feature = "lbf", derive(Json))]
219221
pub enum DelegationCertification {
220222
DelegKey(StakingCredential),
221223
DelegDeregKey(StakingCredential),
@@ -297,6 +299,8 @@ impl IsPlutusData for DelegationCertification {
297299
}
298300

299301
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
302+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
303+
#[cfg_attr(feature = "lbf", derive(Json))]
300304
pub enum ScriptPurpose {
301305
Minting(CurrencySymbol),
302306
Spending(TransactionInput),
@@ -334,6 +338,8 @@ impl IsPlutusData for ScriptPurpose {
334338
}
335339

336340
#[derive(Debug, PartialEq, Eq, Clone)]
341+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
342+
#[cfg_attr(feature = "lbf", derive(Json))]
337343
pub struct TransactionInfo {
338344
pub inputs: Vec<TxInInfo>,
339345
pub outputs: Vec<TransactionOutput>,
@@ -387,6 +393,8 @@ impl IsPlutusData for TransactionInfo {
387393
}
388394

389395
#[derive(Debug, PartialEq, Eq, Clone)]
396+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
397+
#[cfg_attr(feature = "lbf", derive(Json))]
390398
pub struct ScriptContext {
391399
pub purpose: ScriptPurpose,
392400
pub tx_info: TransactionInfo,

src/v1/tuple.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,51 @@
1+
#[cfg(feature = "lbf")]
2+
use lbr_prelude::json::{json_array, Json};
13
use num_bigint::BigInt;
4+
#[cfg(feature = "serde")]
5+
use serde::{Deserialize, Serialize};
26

37
use crate::plutus_data::{
48
parse_constr_with_tag, parse_fixed_len_constr_fields, IsPlutusData, PlutusData, PlutusDataError,
59
};
610

711
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
8-
pub struct Tuple<T, U>(pub (T, U));
12+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13+
pub struct Tuple<T, U>(pub T, pub U);
914

1015
impl<T: IsPlutusData, U: IsPlutusData> IsPlutusData for Tuple<T, U> {
1116
fn to_plutus_data(&self) -> PlutusData {
1217
PlutusData::Constr(
1318
BigInt::from(0u32),
14-
vec![self.0 .0.to_plutus_data(), self.0 .1.to_plutus_data()],
19+
vec![self.0.to_plutus_data(), self.1.to_plutus_data()],
1520
)
1621
}
1722

1823
fn from_plutus_data(data: &PlutusData) -> Result<Self, PlutusDataError> {
1924
let fields = parse_constr_with_tag(data, 0)?;
2025
let [field_0, field_1] = parse_fixed_len_constr_fields(fields)?;
2126

22-
Ok(Self((
27+
Ok(Self(
2328
IsPlutusData::from_plutus_data(field_0)?,
2429
IsPlutusData::from_plutus_data(field_1)?,
25-
)))
30+
))
31+
}
32+
}
33+
34+
#[cfg(feature = "lbf")]
35+
impl<T: Json, U: Json> Json for Tuple<T, U> {
36+
fn to_json(&self) -> serde_json::Value {
37+
json_array(vec![self.0.to_json(), self.1.to_json()])
38+
}
39+
40+
fn from_json(value: &serde_json::Value) -> Result<Self, lbr_prelude::json::Error> {
41+
let vec: Vec<serde_json::Value> = Vec::from_json(value)?;
42+
let [k, v]: [serde_json::Value; 2] = TryFrom::try_from(vec).map_err(|vec: Vec<_>| {
43+
lbr_prelude::json::Error::UnexpectedArrayLength {
44+
got: vec.len(),
45+
wanted: 2,
46+
parser: "v1::tuple::Tuple".into(),
47+
}
48+
})?;
49+
Ok(Self(T::from_json(&k)?, U::from_json(&v)?))
2650
}
2751
}

src/v2/transaction.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ impl IsPlutusData for TxInInfo {
124124
}
125125

126126
#[derive(Debug, PartialEq, Eq, Clone)]
127+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
128+
#[cfg_attr(feature = "lbf", derive(Json))]
127129
pub struct TransactionInfo {
128130
pub inputs: Vec<TxInInfo>,
129131
pub reference_inputs: Vec<TxInInfo>,
@@ -183,6 +185,8 @@ impl IsPlutusData for TransactionInfo {
183185
}
184186

185187
#[derive(Debug, PartialEq, Eq, Clone)]
188+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
189+
#[cfg_attr(feature = "lbf", derive(Json))]
186190
pub struct ScriptContext {
187191
pub purpose: ScriptPurpose,
188192
pub tx_info: TransactionInfo,

tests/json.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod json_roundtrip_tests {
1111

1212
mod v1 {
1313
use super::from_to_json;
14-
use plutus_ledger_api::generators::correct::v1::*;
14+
use plutus_ledger_api::generators::correct::{primitive::arb_integer, v1::*};
1515
use proptest::prelude::*;
1616

1717
proptest! {
@@ -83,6 +83,48 @@ mod json_roundtrip_tests {
8383
assert_eq!(val, from_to_json(&val)?);
8484
}
8585
}
86+
87+
proptest! {
88+
#[test]
89+
fn test_bigint_assoc_map(val in arb_assoc_map(arb_integer(), arb_integer())) {
90+
assert_eq!(val, from_to_json(&val)?);
91+
}
92+
}
93+
94+
proptest! {
95+
#[test]
96+
fn test_bigint_tuple(val in arb_tuple(arb_integer(), arb_integer())) {
97+
assert_eq!(val, from_to_json(&val)?);
98+
}
99+
}
100+
101+
proptest! {
102+
#[test]
103+
fn test_delegation_certification(val in arb_delegation_certification()) {
104+
assert_eq!(val, from_to_json(&val)?)
105+
}
106+
}
107+
108+
proptest! {
109+
#[test]
110+
fn test_script_purpose(val in arb_script_purpose()) {
111+
assert_eq!(val, from_to_json(&val)?)
112+
}
113+
}
114+
115+
proptest! {
116+
#[test]
117+
fn test_transaction_info(val in arb_transaction_info()) {
118+
assert_eq!(val, from_to_json(&val)?)
119+
}
120+
}
121+
122+
proptest! {
123+
#[test]
124+
fn test_script_context(val in arb_script_context()) {
125+
assert_eq!(val, from_to_json(&val)?)
126+
}
127+
}
86128
}
87129
mod v2 {
88130
use super::from_to_json;
@@ -109,5 +151,19 @@ mod json_roundtrip_tests {
109151
assert_eq!(val, from_to_json(&val)?);
110152
}
111153
}
154+
155+
proptest! {
156+
#[test]
157+
fn test_transaction_info(val in arb_transaction_info()) {
158+
assert_eq!(val, from_to_json(&val)?)
159+
}
160+
}
161+
162+
proptest! {
163+
#[test]
164+
fn test_script_context(val in arb_script_context()) {
165+
assert_eq!(val, from_to_json(&val)?)
166+
}
167+
}
112168
}
113169
}

0 commit comments

Comments
 (0)