@@ -4,7 +4,8 @@ use ion_rs::{
4
4
Sequence ,
5
5
} ;
6
6
use partiql_value:: boxed_variant:: {
7
- BoxedVariant , BoxedVariantResult , BoxedVariantType , BoxedVariantValueIntoIterator ,
7
+ BoxedVariant , BoxedVariantResult , BoxedVariantType , BoxedVariantTypeTag ,
8
+ BoxedVariantValueIntoIterator , DynBoxedVariant ,
8
9
} ;
9
10
use partiql_value:: datum:: {
10
11
Datum , DatumCategoryOwned , DatumCategoryRef , DatumLower , DatumLowerResult , DatumSeqOwned ,
@@ -15,8 +16,10 @@ use partiql_value::{Bag, BindingsName, List, Tuple, Value, Variant};
15
16
use peekmore:: { PeekMore , PeekMoreIterator } ;
16
17
#[ cfg( feature = "serde" ) ]
17
18
use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
19
+ use std:: any:: Any ;
18
20
use std:: borrow:: Cow ;
19
21
use std:: cell:: RefCell ;
22
+ use std:: cmp:: Ordering ;
20
23
use std:: fmt:: { Debug , Display , Formatter } ;
21
24
use std:: hash:: { Hash , Hasher } ;
22
25
use std:: ops:: DerefMut ;
@@ -26,15 +29,42 @@ use thiserror::Error;
26
29
#[ derive( Default , Debug , Copy , Clone ) ]
27
30
pub struct BoxedIonType { }
28
31
impl BoxedVariantType for BoxedIonType {
29
- type Doc = BoxedIon ;
30
-
31
- fn construct ( & self , bytes : Vec < u8 > ) -> BoxedVariantResult < Self :: Doc > {
32
- BoxedIon :: parse ( bytes , BoxedIonStreamType :: SingleTLV ) . map_err ( Into :: into )
32
+ fn construct ( & self , bytes : Vec < u8 > ) -> BoxedVariantResult < DynBoxedVariant > {
33
+ BoxedIon :: parse ( bytes , BoxedIonStreamType :: SingleTLV )
34
+ . map_err ( Into :: into )
35
+ . map ( |b| Box :: new ( b ) as DynBoxedVariant )
33
36
}
34
37
35
38
fn name ( & self ) -> & ' static str {
36
39
"ion"
37
40
}
41
+
42
+ fn value_eq ( & self , l : & DynBoxedVariant , r : & DynBoxedVariant ) -> bool {
43
+ let ( l, r) = get_values ( l, r) ;
44
+
45
+ l. eq ( r)
46
+ }
47
+
48
+ fn value_cmp ( & self , l : & DynBoxedVariant , r : & DynBoxedVariant ) -> Ordering {
49
+ let ( l, r) = get_values ( l, r) ;
50
+
51
+ l. cmp ( r)
52
+ }
53
+ }
54
+
55
+ #[ inline]
56
+ fn get_value ( l : & DynBoxedVariant ) -> & BoxedIon {
57
+ l. as_any ( ) . downcast_ref :: < BoxedIon > ( ) . expect ( "IonValue" )
58
+ }
59
+
60
+ #[ inline]
61
+ fn get_values < ' a , ' b > (
62
+ l : & ' a DynBoxedVariant ,
63
+ r : & ' b DynBoxedVariant ,
64
+ ) -> ( & ' a BoxedIon , & ' b BoxedIon ) {
65
+ debug_assert_eq ! ( * l. type_tag( ) , * r. type_tag( ) ) ;
66
+
67
+ ( get_value ( l) , get_value ( r) )
38
68
}
39
69
40
70
/// Errors in boxed Ion.
@@ -116,6 +146,14 @@ impl Hash for BoxedIon {
116
146
117
147
#[ cfg_attr( feature = "serde" , typetag:: serde) ]
118
148
impl BoxedVariant for BoxedIon {
149
+ fn type_tag ( & self ) -> BoxedVariantTypeTag {
150
+ Box :: new ( BoxedIonType { } )
151
+ }
152
+
153
+ fn as_any ( & self ) -> & dyn Any {
154
+ self
155
+ }
156
+
119
157
fn into_dyn_iter ( self : Box < Self > ) -> BoxedVariantResult < BoxedVariantValueIntoIterator > {
120
158
let iter = self . try_into_iter ( ) ?;
121
159
@@ -127,13 +165,19 @@ impl BoxedVariant for BoxedIon {
127
165
match & self . doc {
128
166
BoxedIonValue :: Stream ( ) => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
129
167
BoxedIonValue :: Sequence ( _) => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
130
- BoxedIonValue :: Value ( elt) => match elt. ion_type ( ) {
131
- IonType :: List => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
132
- IonType :: SExp => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
133
- IonType :: Null => DatumCategoryRef :: Null ,
134
- IonType :: Struct => DatumCategoryRef :: Tuple ( DatumTupleRef :: Dynamic ( self ) ) ,
135
- _ => DatumCategoryRef :: Scalar ( DatumValueRef :: Lower ( self ) ) ,
136
- } ,
168
+ BoxedIonValue :: Value ( elt) => {
169
+ if elt. is_null ( ) {
170
+ DatumCategoryRef :: Null
171
+ } else {
172
+ match elt. ion_type ( ) {
173
+ IonType :: List => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
174
+ IonType :: SExp => DatumCategoryRef :: Sequence ( DatumSeqRef :: Dynamic ( self ) ) ,
175
+ IonType :: Null => DatumCategoryRef :: Null ,
176
+ IonType :: Struct => DatumCategoryRef :: Tuple ( DatumTupleRef :: Dynamic ( self ) ) ,
177
+ _ => DatumCategoryRef :: Scalar ( DatumValueRef :: Lower ( self ) ) ,
178
+ }
179
+ }
180
+ }
137
181
}
138
182
}
139
183
@@ -143,44 +187,70 @@ impl BoxedVariant for BoxedIon {
143
187
BoxedIonValue :: Sequence ( _) => {
144
188
DatumCategoryOwned :: Sequence ( DatumSeqOwned :: Dynamic ( self ) )
145
189
}
146
- BoxedIonValue :: Value ( elt) => match elt. ion_type ( ) {
147
- IonType :: List => DatumCategoryOwned :: Sequence ( DatumSeqOwned :: Dynamic ( self ) ) ,
148
- IonType :: SExp => DatumCategoryOwned :: Sequence ( DatumSeqOwned :: Dynamic ( self ) ) ,
149
- IonType :: Null => DatumCategoryOwned :: Null ,
150
- IonType :: Struct => DatumCategoryOwned :: Tuple ( DatumTupleOwned :: Dynamic ( self ) ) ,
151
- _ => DatumCategoryOwned :: Scalar ( DatumValueOwned :: Value ( self . into_value ( ) ) ) ,
152
- } ,
190
+ BoxedIonValue :: Value ( elt) => {
191
+ if elt. is_null ( ) {
192
+ DatumCategoryOwned :: Null
193
+ } else {
194
+ match elt. ion_type ( ) {
195
+ IonType :: List => DatumCategoryOwned :: Sequence ( DatumSeqOwned :: Dynamic ( self ) ) ,
196
+ IonType :: SExp => DatumCategoryOwned :: Sequence ( DatumSeqOwned :: Dynamic ( self ) ) ,
197
+ IonType :: Null => DatumCategoryOwned :: Null ,
198
+ IonType :: Struct => {
199
+ DatumCategoryOwned :: Tuple ( DatumTupleOwned :: Dynamic ( self ) )
200
+ }
201
+ _ => DatumCategoryOwned :: Scalar ( DatumValueOwned :: Value ( self . into_value ( ) ) ) ,
202
+ }
203
+ }
204
+ }
153
205
}
154
206
}
155
207
}
156
208
209
+ impl PartialEq < Self > for BoxedIon {
210
+ fn eq ( & self , other : & Self ) -> bool {
211
+ self . doc . eq ( & other. doc )
212
+ }
213
+ }
214
+
215
+ impl Eq for BoxedIon { }
216
+
217
+ impl PartialOrd for BoxedIon {
218
+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
219
+ Some ( self . cmp ( other) )
220
+ }
221
+ }
222
+ impl Ord for BoxedIon {
223
+ fn cmp ( & self , other : & Self ) -> Ordering {
224
+ // TODO lowering just to compare is costly... Either find a better way, or lift this out of the extension
225
+ self . lower ( ) . unwrap ( ) . cmp ( & other. lower ( ) . unwrap ( ) )
226
+ }
227
+ }
228
+
157
229
impl DatumLower < Value > for BoxedIon {
158
230
fn into_lower ( self ) -> DatumLowerResult < Value > {
159
231
let Self { ctx, doc } = self ;
160
- match doc {
232
+ let pval = match doc {
161
233
BoxedIonValue :: Stream ( ) => todo ! ( "into_lower stream" ) ,
162
- BoxedIonValue :: Sequence ( _) => todo ! ( "into_lower seq" ) ,
163
- BoxedIonValue :: Value ( elt) => {
164
- let pval = elt. into_partiql_value ( ) ?;
165
- Ok ( match pval {
166
- PartiqlValueTarget :: Atom ( val) => val,
167
- PartiqlValueTarget :: List ( l) => {
168
- let vals = l. into_iter ( ) . map ( |elt| Self :: new_value ( elt, ctx. clone ( ) ) ) ;
169
- List :: from_iter ( vals) . into ( )
170
- }
171
- PartiqlValueTarget :: Bag ( b) => {
172
- let vals = b. into_iter ( ) . map ( |elt| Self :: new_value ( elt, ctx. clone ( ) ) ) ;
173
- Bag :: from_iter ( vals) . into ( )
174
- }
175
- PartiqlValueTarget :: Struct ( s) => {
176
- let vals = s
177
- . into_iter ( )
178
- . map ( |( key, elt) | ( key, Self :: new_value ( elt, ctx. clone ( ) ) ) ) ;
179
- Tuple :: from_iter ( vals) . into ( )
180
- }
181
- } )
234
+ BoxedIonValue :: Sequence ( seq) => seq. into_partiql_value ( ) ?,
235
+ BoxedIonValue :: Value ( elt) => elt. into_partiql_value ( ) ?,
236
+ } ;
237
+ Ok ( match pval {
238
+ PartiqlValueTarget :: Atom ( val) => val,
239
+ PartiqlValueTarget :: List ( l) => {
240
+ let vals = l. into_iter ( ) . map ( |elt| Self :: new_value ( elt, ctx. clone ( ) ) ) ;
241
+ List :: from_iter ( vals) . into ( )
182
242
}
183
- }
243
+ PartiqlValueTarget :: Bag ( b) => {
244
+ let vals = b. into_iter ( ) . map ( |elt| Self :: new_value ( elt, ctx. clone ( ) ) ) ;
245
+ Bag :: from_iter ( vals) . into ( )
246
+ }
247
+ PartiqlValueTarget :: Struct ( s) => {
248
+ let vals = s
249
+ . into_iter ( )
250
+ . map ( |( key, elt) | ( key, Self :: new_value ( elt, ctx. clone ( ) ) ) ) ;
251
+ Tuple :: from_iter ( vals) . into ( )
252
+ }
253
+ } )
184
254
}
185
255
186
256
fn into_lower_boxed ( self : Box < Self > ) -> DatumLowerResult < Value > {
@@ -307,7 +377,7 @@ impl<'a> RefTupleView<'a, Value> for BoxedIon {
307
377
}
308
378
309
379
impl OwnedTupleView < Value > for BoxedIon {
310
- fn take_val ( self , k : & BindingsName < ' _ > ) -> Option < Value > {
380
+ fn take_val ( self , _k : & BindingsName < ' _ > ) -> Option < Value > {
311
381
todo ! ( )
312
382
}
313
383
@@ -461,6 +531,18 @@ enum BoxedIonValue {
461
531
Sequence ( Sequence ) ,
462
532
}
463
533
534
+ impl PartialEq < Self > for BoxedIonValue {
535
+ fn eq ( & self , other : & Self ) -> bool {
536
+ match ( self , other) {
537
+ ( BoxedIonValue :: Value ( l) , BoxedIonValue :: Value ( r) ) => l == r,
538
+ ( BoxedIonValue :: Sequence ( l) , BoxedIonValue :: Sequence ( r) ) => l == r,
539
+ _ => false ,
540
+ }
541
+ }
542
+ }
543
+
544
+ impl Eq for BoxedIonValue { }
545
+
464
546
impl From < Element > for BoxedIonValue {
465
547
fn from ( value : Element ) -> Self {
466
548
BoxedIonValue :: Value ( value)
0 commit comments