1
1
use std:: collections:: HashMap ;
2
2
3
- use borsh:: BorshSerialize ;
3
+ use borsh:: { BorshDeserialize , BorshSerialize } ;
4
4
5
5
mod serde_json_value {
6
+ pub use de:: deserialize_value;
6
7
pub use ser:: serialize_value;
7
8
mod ser {
8
9
use borsh:: {
@@ -11,7 +12,7 @@ mod serde_json_value {
11
12
} ;
12
13
use core:: convert:: TryFrom ;
13
14
14
- /// this is mutually recursive with serialize_array and serialize_map
15
+ /// this is mutually recursive with ` serialize_array` and ` serialize_map`
15
16
pub fn serialize_value < W : Write > ( value : & serde_json:: Value , writer : & mut W ) -> Result < ( ) > {
16
17
match value {
17
18
serde_json:: Value :: Null => 0_u8 . serialize ( writer) ,
@@ -38,11 +39,37 @@ mod serde_json_value {
38
39
}
39
40
}
40
41
41
- /// this is mutually recursive with serialize_value
42
- fn serialize_array < W : Write > (
43
- array : & Vec < serde_json:: Value > ,
44
- writer : & mut W ,
45
- ) -> Result < ( ) > {
42
+ fn serialize_number < W : Write > ( number : & serde_json:: Number , writer : & mut W ) -> Result < ( ) > {
43
+ // A JSON number can either be a non-negative integer (represented in
44
+ // serde_json by a u64), a negative integer (by an i64), or a non-integer
45
+ // (by an f64).
46
+ // We identify these cases with the following single-byte discriminants:
47
+ // 0 - u64
48
+ // 1 - i64
49
+ // 2 - f64
50
+ if let Some ( u) = number. as_u64 ( ) {
51
+ 0_u8 . serialize ( writer) ?;
52
+ return u. serialize ( writer) ;
53
+ }
54
+
55
+ if let Some ( i) = number. as_i64 ( ) {
56
+ 1_u8 . serialize ( writer) ?;
57
+ return i. serialize ( writer) ;
58
+ }
59
+
60
+ if let Some ( f) = number. as_f64 ( ) {
61
+ 2_u8 . serialize ( writer) ?;
62
+ return f. serialize ( writer) ;
63
+ }
64
+
65
+ // technically, it should not be unreachable, but an error instead,
66
+ // as assumption about unreachable depends on private implementation detail
67
+ // but it's fine to leave it be unreachable! for an example
68
+ unreachable ! ( "number is neither a u64, i64, nor f64" ) ;
69
+ }
70
+
71
+ /// this is mutually recursive with `serialize_value`
72
+ fn serialize_array < W : Write > ( array : & Vec < serde_json:: Value > , writer : & mut W ) -> Result < ( ) > {
46
73
writer. write_all (
47
74
& ( u32:: try_from ( array. len ( ) ) . map_err ( |_| ErrorKind :: InvalidData ) ?) . to_le_bytes ( ) ,
48
75
) ?;
@@ -52,7 +79,7 @@ mod serde_json_value {
52
79
Ok ( ( ) )
53
80
}
54
81
55
- /// this is mutually recursive with serialize_value
82
+ /// this is mutually recursive with ` serialize_value`
56
83
fn serialize_map < W : Write > (
57
84
map : & serde_json:: Map < String , serde_json:: Value > ,
58
85
writer : & mut W ,
@@ -69,73 +96,154 @@ mod serde_json_value {
69
96
70
97
Ok ( ( ) )
71
98
}
99
+ }
100
+ mod de {
101
+ use borsh:: {
102
+ io:: { Error , ErrorKind , Read , Result } ,
103
+ BorshDeserialize ,
104
+ } ;
72
105
73
- fn serialize_number < W : Write > ( number : & serde_json:: Number , writer : & mut W ) -> Result < ( ) > {
74
- // A JSON number can either be a non-negative integer (represented in
75
- // serde_json by a u64), a negative integer (by an i64), or a non-integer
76
- // (by an f64).
77
- // We identify these cases with the following single-byte discriminants:
78
- // 0 - u64
79
- // 1 - i64
80
- // 2 - f64
81
- if let Some ( u) = number. as_u64 ( ) {
82
- 0_u8 . serialize ( writer) ?;
83
- return u. serialize ( writer) ;
106
+ fn hint_cautious < T > ( hint : u32 ) -> usize {
107
+ let el_size = core:: mem:: size_of :: < T > ( ) as u32 ;
108
+ core:: cmp:: max ( core:: cmp:: min ( hint, 4096 / el_size) , 1 ) as usize
109
+ }
110
+
111
+ /// this is mutually recursive with `deserialize_array`, `deserialize_map`
112
+ pub fn deserialize_value < R : Read > ( reader : & mut R ) -> Result < serde_json:: Value > {
113
+ let flag: u8 = BorshDeserialize :: deserialize_reader ( reader) ?;
114
+ match flag {
115
+ 0 => Ok ( serde_json:: Value :: Null ) ,
116
+ 1 => {
117
+ let b: bool = BorshDeserialize :: deserialize_reader ( reader) ?;
118
+ Ok ( serde_json:: Value :: Bool ( b) )
119
+ }
120
+ 2 => {
121
+ let n: serde_json:: Number = deserialize_number ( reader) ?;
122
+ Ok ( serde_json:: Value :: Number ( n) )
123
+ }
124
+ 3 => {
125
+ let s: String = BorshDeserialize :: deserialize_reader ( reader) ?;
126
+ Ok ( serde_json:: Value :: String ( s) )
127
+ }
128
+ 4 => {
129
+ let a: Vec < serde_json:: Value > = deserialize_array ( reader) ?;
130
+ Ok ( serde_json:: Value :: Array ( a) )
131
+ }
132
+ 5 => {
133
+ let o: serde_json:: Map < _ , _ > = deserialize_map ( reader) ?;
134
+ Ok ( serde_json:: Value :: Object ( o) )
135
+ }
136
+ _ => {
137
+ let msg = format ! (
138
+ "Invalid JSON value representation: {}. The first byte must be 0-5" ,
139
+ flag
140
+ ) ;
141
+
142
+ Err ( Error :: new ( ErrorKind :: InvalidData , msg) )
143
+ }
84
144
}
145
+ }
85
146
86
- if let Some ( i) = number. as_i64 ( ) {
87
- 1_u8 . serialize ( writer) ?;
88
- return i. serialize ( writer) ;
147
+ fn deserialize_number < R : Read > ( reader : & mut R ) -> Result < serde_json:: Number > {
148
+ let flag: u8 = BorshDeserialize :: deserialize_reader ( reader) ?;
149
+ match flag {
150
+ 0 => {
151
+ let u: u64 = BorshDeserialize :: deserialize_reader ( reader) ?;
152
+ Ok ( u. into ( ) )
153
+ }
154
+ 1 => {
155
+ let i: i64 = BorshDeserialize :: deserialize_reader ( reader) ?;
156
+ Ok ( i. into ( ) )
157
+ }
158
+ 2 => {
159
+ let f: f64 = BorshDeserialize :: deserialize_reader ( reader) ?;
160
+ // This returns None if the number is a NaN or +/-Infinity,
161
+ // which are not valid JSON numbers.
162
+ serde_json:: Number :: from_f64 ( f) . ok_or_else ( || {
163
+ let msg = format ! ( "Invalid JSON number: {}" , f) ;
164
+
165
+ Error :: new ( ErrorKind :: InvalidData , msg)
166
+ } )
167
+ }
168
+ _ => {
169
+ let msg = format ! (
170
+ "Invalid JSON number representation: {}. The first byte must be 0-2" ,
171
+ flag
172
+ ) ;
173
+
174
+ Err ( Error :: new ( ErrorKind :: InvalidData , msg) )
175
+ }
89
176
}
177
+ }
90
178
91
- if let Some ( f) = number. as_f64 ( ) {
92
- 2_u8 . serialize ( writer) ?;
93
- return f. serialize ( writer) ;
179
+ /// this is mutually recursive with `deserialize_value`
180
+ fn deserialize_array < R : Read > ( reader : & mut R ) -> Result < Vec < serde_json:: Value > > {
181
+ let len = u32:: deserialize_reader ( reader) ?;
182
+ let mut result = Vec :: with_capacity ( hint_cautious :: < ( String , serde_json:: Value ) > ( len) ) ;
183
+ for _ in 0 ..len {
184
+ let value = deserialize_value ( reader) ?;
185
+ result. push ( value) ;
94
186
}
187
+ Ok ( result)
188
+ }
95
189
96
- unreachable ! ( "number is neither a u64, i64, nor f64" ) ;
190
+ /// this is mutually recursive with `deserialize_value`
191
+ fn deserialize_map < R : Read > (
192
+ reader : & mut R ,
193
+ ) -> Result < serde_json:: Map < String , serde_json:: Value > > {
194
+ // The implementation here is identical to that of BTreeMap<String, serde_json::Value>.
195
+
196
+ let vec: Vec < ( String , serde_json:: Value ) > = {
197
+ let len = u32:: deserialize_reader ( reader) ?;
198
+ let mut result =
199
+ Vec :: with_capacity ( hint_cautious :: < ( String , serde_json:: Value ) > ( len) ) ;
200
+ for _ in 0 ..len {
201
+ let pair = {
202
+ let key = String :: deserialize_reader ( reader) ?;
203
+ let value = deserialize_value ( reader) ?;
204
+ ( key, value)
205
+ } ;
206
+ result. push ( pair) ;
207
+ }
208
+ result
209
+ } ;
210
+
211
+ Ok ( vec. into_iter ( ) . collect ( ) )
97
212
}
98
213
}
99
214
}
100
215
101
- mod map_of_serde_json_value {
102
- pub use ser:: serialize_map;
103
-
104
- mod ser {
216
+ mod borsh_wrapper {
217
+ use borsh:: { BorshDeserialize , BorshSerialize } ;
105
218
106
- use borsh:: {
107
- io:: { ErrorKind , Result , Write } ,
108
- BorshSerialize ,
109
- } ;
110
- use core:: convert:: TryFrom ;
111
- use std:: collections:: HashMap ;
219
+ #[ derive( Debug , PartialEq , Eq , BorshSerialize , BorshDeserialize ) ]
220
+ pub struct SerdeJsonBorshWrapper (
221
+ #[ borsh(
222
+ serialize_with = "super::serde_json_value::serialize_value" ,
223
+ deserialize_with = "super::serde_json_value::deserialize_value"
224
+ ) ]
225
+ pub serde_json:: Value ,
226
+ ) ;
112
227
113
- pub fn serialize_map < W : Write > ( value : & HashMap < String , serde_json:: Value > , writer : & mut W ) -> Result < ( ) > {
114
- let mut vec = value. iter ( ) . collect :: < Vec < _ > > ( ) ;
115
- vec. sort_by ( |( a, _) , ( b, _) | a. cmp ( b) ) ;
116
- u32:: try_from ( vec. len ( ) )
117
- . map_err ( |_| ErrorKind :: InvalidData ) ?
118
- . serialize ( writer) ?;
119
- for kv in vec {
120
- kv. 0 . serialize ( writer) ?;
121
- crate :: serde_json_value:: serialize_value ( kv. 1 , writer) ?;
122
- }
123
- Ok ( ( ) )
228
+ impl From < serde_json:: Value > for SerdeJsonBorshWrapper {
229
+ fn from ( value : serde_json:: Value ) -> Self {
230
+ Self ( value)
124
231
}
125
-
126
232
}
127
-
128
- }
129
233
130
- #[ derive( BorshSerialize ) ]
131
- struct SerdeJsonAsField {
132
- #[ borsh(
133
- serialize_with = "map_of_serde_json_value::serialize_map" ,
134
- ) ]
135
- examples : HashMap < String , serde_json:: Value > ,
234
+ impl From < SerdeJsonBorshWrapper > for serde_json:: Value {
235
+ fn from ( value : SerdeJsonBorshWrapper ) -> Self {
236
+ value. 0
237
+ }
238
+ }
136
239
}
137
240
241
+ use borsh_wrapper:: SerdeJsonBorshWrapper ;
138
242
243
+ #[ derive( Debug , PartialEq , Eq , BorshSerialize , BorshDeserialize ) ]
244
+ struct SerdeJsonAsField {
245
+ pub examples : HashMap < String , SerdeJsonBorshWrapper > ,
246
+ }
139
247
140
248
fn main ( ) {
141
249
let original = serde_json:: json!( {
@@ -189,12 +297,32 @@ fn main() {
189
297
} ) ;
190
298
191
299
let mut examples = HashMap :: new ( ) ;
192
- examples. insert ( "Larry Jake Pumpkin" . into ( ) , original) ;
300
+ examples. insert ( "Larry Jake Pumpkin" . into ( ) , original. clone ( ) . into ( ) ) ;
193
301
194
- let complex_struct = SerdeJsonAsField {
195
- examples,
196
- } ;
302
+ let complex_struct = SerdeJsonAsField { examples } ;
197
303
let serialized = borsh:: to_vec ( & complex_struct) . unwrap ( ) ;
198
304
199
- println ! ( "{:#?}" , serialized) ;
305
+ let mut deserialized: SerdeJsonAsField = borsh:: from_slice ( & serialized) . unwrap ( ) ;
306
+
307
+ assert_eq ! ( complex_struct, deserialized) ;
308
+
309
+ let deserialized_value: serde_json:: Value = deserialized
310
+ . examples
311
+ . remove ( "Larry Jake Pumpkin" )
312
+ . expect ( "key present" )
313
+ . into ( ) ;
314
+
315
+ assert_eq ! ( original, deserialized_value) ;
316
+
317
+ let number = deserialized_value
318
+ . get ( "array_of_numbers" )
319
+ . expect ( "has key" )
320
+ . as_array ( )
321
+ . expect ( "is array" )
322
+ . get ( 5 )
323
+ . expect ( "has index" )
324
+ . as_i64 ( )
325
+ . expect ( "is i64" ) ;
326
+
327
+ assert_eq ! ( number, 34798324 ) ;
200
328
}
0 commit comments