@@ -24,12 +24,11 @@ pub enum TxDatumError {
24
24
pub struct TxDatum ( pub String ) ;
25
25
26
26
impl TxDatum {
27
- /// Retrieves the nth field of the datum with given type
28
- pub fn get_nth_field_by_type (
27
+ /// Retrieves the fields of the datum with given type
28
+ pub fn get_fields_by_type (
29
29
& self ,
30
30
type_name : & TxDatumFieldTypeName ,
31
- index : usize ,
32
- ) -> Result < Value , Box < dyn StdError > > {
31
+ ) -> Result < Vec < Value > , Box < dyn StdError > > {
33
32
let tx_datum_raw = & self . 0 ;
34
33
// 1- Parse the Utxo raw data to a hashmap
35
34
let v: HashMap < String , Value > = serde_json:: from_str ( tx_datum_raw) . map_err ( |e| {
@@ -48,22 +47,28 @@ impl TxDatum {
48
47
)
49
48
} ) ?;
50
49
// 3- Filter the vec (keep the ones that match the given type), and retrieve the nth entry of this filtered vec
51
- let field_value = fields
50
+ Ok ( fields
52
51
. iter ( )
53
52
. filter ( |& field| field. get ( type_name. to_string ( ) ) . is_some ( ) )
54
- . nth ( index)
53
+ . map ( |field| field. get ( type_name. to_string ( ) ) . unwrap ( ) . to_owned ( ) )
54
+ . collect :: < _ > ( ) )
55
+ }
56
+
57
+ /// Retrieves the nth field of the datum with given type
58
+ pub fn get_nth_field_by_type (
59
+ & self ,
60
+ type_name : & TxDatumFieldTypeName ,
61
+ index : usize ,
62
+ ) -> Result < Value , Box < dyn StdError > > {
63
+ Ok ( self
64
+ . get_fields_by_type ( type_name) ?
65
+ . get ( index)
55
66
. ok_or_else ( || {
56
67
TxDatumError :: InvalidContent (
57
- format ! (
58
- "Error: missing field at index {index}, tx datum was = '{tx_datum_raw}'"
59
- )
60
- . into ( ) ,
68
+ format ! ( "Error: missing field at index {index}" ) . into ( ) ,
61
69
)
62
70
} ) ?
63
- . get ( type_name. to_string ( ) )
64
- . unwrap ( ) ;
65
-
66
- Ok ( field_value. to_owned ( ) )
71
+ . to_owned ( ) )
67
72
}
68
73
}
69
74
@@ -101,9 +106,29 @@ impl TxDatumBuilder {
101
106
102
107
/// Add a field to the builder
103
108
pub fn add_field ( & mut self , field_value : TxDatumFieldValue ) -> & mut TxDatumBuilder {
104
- let mut field = HashMap :: new ( ) ;
105
- field. insert ( TxDatumFieldTypeName :: from ( & field_value) , field_value) ;
106
- self . fields . push ( field) ;
109
+ match & field_value {
110
+ TxDatumFieldValue :: Bytes ( datum_str) => {
111
+ // TODO: Remove this chunking of the bytes fields once the cardano-cli 1.36.0+ is released
112
+ // The bytes fields are currently limited to 128 bytes and need to be chunked in multiple fields
113
+ let field_type = TxDatumFieldTypeName :: from ( & field_value) ;
114
+ let field_value_chunks = datum_str. as_bytes ( ) . chunks ( 128 ) ;
115
+ for field_value_chunk in field_value_chunks {
116
+ let mut field = HashMap :: new ( ) ;
117
+ field. insert (
118
+ field_type,
119
+ TxDatumFieldValue :: Bytes (
120
+ std:: str:: from_utf8 ( field_value_chunk) . unwrap ( ) . to_string ( ) ,
121
+ ) ,
122
+ ) ;
123
+ self . fields . push ( field) ;
124
+ }
125
+ }
126
+ _ => {
127
+ let mut field = HashMap :: new ( ) ;
128
+ field. insert ( TxDatumFieldTypeName :: from ( & field_value) , field_value) ;
129
+ self . fields . push ( field) ;
130
+ }
131
+ }
107
132
108
133
self
109
134
}
@@ -135,6 +160,7 @@ mod test {
135
160
. add_field ( TxDatumFieldValue :: Bytes ( "bytes1" . to_string ( ) ) )
136
161
. add_field ( TxDatumFieldValue :: Bytes ( "bytes2" . to_string ( ) ) )
137
162
. add_field ( TxDatumFieldValue :: Int ( 2 ) )
163
+ . add_field ( TxDatumFieldValue :: Bytes ( "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" . to_string ( ) ) )
138
164
. build ( )
139
165
. expect ( "tx_datum build should not fail" ) ;
140
166
tx_datum
@@ -143,7 +169,7 @@ mod test {
143
169
#[ test]
144
170
fn test_build_tx_datum ( ) {
145
171
let tx_datum = dummy_tx_datum ( ) ;
146
- let tx_datum_expected = TxDatum ( r#"{"constructor":0,"fields":[{"bytes":"bytes0"},{"int":0},{"int":1},{"bytes":"bytes1"},{"bytes":"bytes2"},{"int":2}]}"# . to_string ( ) ) ;
172
+ let tx_datum_expected = TxDatum ( r#"{"constructor":0,"fields":[{"bytes":"bytes0"},{"int":0},{"int":1},{"bytes":"bytes1"},{"bytes":"bytes2"},{"int":2},{"bytes":"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567"},{"bytes":"8901234567890123456789"} ]}"# . to_string ( ) ) ;
147
173
assert_eq ! ( tx_datum_expected, tx_datum) ;
148
174
}
149
175
0 commit comments