Skip to content

Commit 67777c2

Browse files
authored
Add encoding/decoding to/from Ion Element (#391)
1 parent a2e6bde commit 67777c2

File tree

4 files changed

+360
-116
lines changed

4 files changed

+360
-116
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
9+
### Changed
10+
### Added
11+
- Add ability for partiql-extension-ion extension encoding/decoding of `Value` to/from Ion `Element`
12+
### Fixes
913

1014
## [0.5.0] - 2023-06-06
1115
### Changed

extension/partiql-extension-ion/src/decode.rs

Lines changed: 104 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use delegate::delegate;
2-
use ion_rs::{Decimal, Int, IonError, IonReader, IonType, Reader, StreamItem};
2+
use ion_rs::{Decimal, Int, IonError, IonReader, IonType, StreamItem, Symbol};
33
use once_cell::sync::Lazy;
44
use partiql_value::{Bag, DateTime, List, Tuple, Value};
55
use regex::RegexSet;
@@ -89,7 +89,10 @@ impl IonDecoderBuilder {
8989
}
9090

9191
/// Create a decoder given the previously specified config and an ion [`Reader`].
92-
pub fn build(self, reader: Reader) -> Result<IonValueIter, IonDecodeError> {
92+
pub fn build<'a>(
93+
self,
94+
reader: impl 'a + IonReader<Item = StreamItem, Symbol = Symbol>,
95+
) -> Result<IonValueIter<'a>, IonDecodeError> {
9396
let decoder = SimpleIonValueDecoder {};
9497
let inner: Box<dyn Iterator<Item = IonDecodeResult>> = match self.config.mode {
9598
crate::Encoding::Ion => Box::new(IonValueIterInner { reader, decoder }),
@@ -123,17 +126,19 @@ impl<'a> Iterator for IonValueIter<'a> {
123126
}
124127
}
125128

126-
struct IonValueIterInner<'a, D>
129+
struct IonValueIterInner<D, R>
127130
where
128-
D: IonValueDecoder,
131+
D: IonValueDecoder<R>,
132+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
129133
{
130-
reader: Reader<'a>,
134+
reader: R,
131135
decoder: D,
132136
}
133137

134-
impl<'a, P> Iterator for IonValueIterInner<'a, P>
138+
impl<D, R> Iterator for IonValueIterInner<D, R>
135139
where
136-
P: IonValueDecoder,
140+
D: IonValueDecoder<R>,
141+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
137142
{
138143
type Item = IonDecodeResult;
139144

@@ -147,9 +152,12 @@ where
147152
}
148153
}
149154

150-
trait IonValueDecoder {
155+
trait IonValueDecoder<R>
156+
where
157+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
158+
{
151159
#[inline]
152-
fn decode_value(&self, reader: &mut Reader, typ: IonType) -> IonDecodeResult {
160+
fn decode_value(&self, reader: &mut R, typ: IonType) -> IonDecodeResult {
153161
match typ {
154162
IonType::Null => self.decode_null(reader),
155163
IonType::Bool => self.decode_bool(reader),
@@ -167,19 +175,19 @@ trait IonValueDecoder {
167175
}
168176
}
169177

170-
fn decode_null(&self, reader: &mut Reader) -> IonDecodeResult;
171-
fn decode_bool(&self, reader: &mut Reader) -> IonDecodeResult;
172-
fn decode_int(&self, reader: &mut Reader) -> IonDecodeResult;
173-
fn decode_float(&self, reader: &mut Reader) -> IonDecodeResult;
174-
fn decode_decimal(&self, reader: &mut Reader) -> IonDecodeResult;
175-
fn decode_timestamp(&self, reader: &mut Reader) -> IonDecodeResult;
176-
fn decode_symbol(&self, reader: &mut Reader) -> IonDecodeResult;
177-
fn decode_string(&self, reader: &mut Reader) -> IonDecodeResult;
178-
fn decode_clob(&self, reader: &mut Reader) -> IonDecodeResult;
179-
fn decode_blob(&self, reader: &mut Reader) -> IonDecodeResult;
180-
fn decode_list(&self, reader: &mut Reader) -> IonDecodeResult;
181-
fn decode_sexp(&self, reader: &mut Reader) -> IonDecodeResult;
182-
fn decode_struct(&self, reader: &mut Reader) -> IonDecodeResult;
178+
fn decode_null(&self, reader: &mut R) -> IonDecodeResult;
179+
fn decode_bool(&self, reader: &mut R) -> IonDecodeResult;
180+
fn decode_int(&self, reader: &mut R) -> IonDecodeResult;
181+
fn decode_float(&self, reader: &mut R) -> IonDecodeResult;
182+
fn decode_decimal(&self, reader: &mut R) -> IonDecodeResult;
183+
fn decode_timestamp(&self, reader: &mut R) -> IonDecodeResult;
184+
fn decode_symbol(&self, reader: &mut R) -> IonDecodeResult;
185+
fn decode_string(&self, reader: &mut R) -> IonDecodeResult;
186+
fn decode_clob(&self, reader: &mut R) -> IonDecodeResult;
187+
fn decode_blob(&self, reader: &mut R) -> IonDecodeResult;
188+
fn decode_list(&self, reader: &mut R) -> IonDecodeResult;
189+
fn decode_sexp(&self, reader: &mut R) -> IonDecodeResult;
190+
fn decode_struct(&self, reader: &mut R) -> IonDecodeResult;
183191
}
184192

185193
fn ion_decimal_to_decimal(ion_dec: Decimal) -> Result<rust_decimal::Decimal, rust_decimal::Error> {
@@ -192,38 +200,41 @@ fn ion_decimal_to_decimal(ion_dec: Decimal) -> Result<rust_decimal::Decimal, rus
192200

193201
struct SimpleIonValueDecoder {}
194202

195-
impl IonValueDecoder for SimpleIonValueDecoder {
203+
impl<R> IonValueDecoder<R> for SimpleIonValueDecoder
204+
where
205+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
206+
{
196207
#[inline]
197-
fn decode_null(&self, _: &mut Reader) -> IonDecodeResult {
208+
fn decode_null(&self, _: &mut R) -> IonDecodeResult {
198209
Ok(Value::Null)
199210
}
200211

201212
#[inline]
202-
fn decode_bool(&self, reader: &mut Reader) -> IonDecodeResult {
213+
fn decode_bool(&self, reader: &mut R) -> IonDecodeResult {
203214
Ok(Value::Boolean(reader.read_bool()?))
204215
}
205216

206217
#[inline]
207-
fn decode_int(&self, reader: &mut Reader) -> IonDecodeResult {
218+
fn decode_int(&self, reader: &mut R) -> IonDecodeResult {
208219
match reader.read_int()? {
209220
Int::I64(i) => Ok(Value::Integer(i)),
210221
Int::BigInt(_) => Err(IonDecodeError::UnsupportedType("bigint")),
211222
}
212223
}
213224

214225
#[inline]
215-
fn decode_float(&self, reader: &mut Reader) -> IonDecodeResult {
226+
fn decode_float(&self, reader: &mut R) -> IonDecodeResult {
216227
Ok(Value::Real(reader.read_f64()?.into()))
217228
}
218229

219230
#[inline]
220-
fn decode_decimal(&self, reader: &mut Reader) -> IonDecodeResult {
231+
fn decode_decimal(&self, reader: &mut R) -> IonDecodeResult {
221232
let dec = ion_decimal_to_decimal(reader.read_decimal()?);
222233
Ok(Value::Decimal(dec?))
223234
}
224235

225236
#[inline]
226-
fn decode_timestamp(&self, reader: &mut Reader) -> IonDecodeResult {
237+
fn decode_timestamp(&self, reader: &mut R) -> IonDecodeResult {
227238
let ts = reader.read_timestamp()?;
228239
let offset = ts.offset();
229240
let datetime = DateTime::from_ymdhms_nano_offset_minutes(
@@ -242,47 +253,50 @@ impl IonValueDecoder for SimpleIonValueDecoder {
242253
}
243254

244255
#[inline]
245-
fn decode_symbol(&self, reader: &mut Reader) -> IonDecodeResult {
256+
fn decode_symbol(&self, reader: &mut R) -> IonDecodeResult {
246257
Ok(Value::String(Box::new(
247258
reader.read_symbol()?.text_or_error()?.to_string(),
248259
)))
249260
}
250261

251262
#[inline]
252-
fn decode_string(&self, reader: &mut Reader) -> IonDecodeResult {
263+
fn decode_string(&self, reader: &mut R) -> IonDecodeResult {
253264
Ok(Value::String(Box::new(
254265
reader.read_string()?.text().to_string(),
255266
)))
256267
}
257268

258269
#[inline]
259-
fn decode_clob(&self, reader: &mut Reader) -> IonDecodeResult {
270+
fn decode_clob(&self, reader: &mut R) -> IonDecodeResult {
260271
Ok(Value::Blob(Box::new(reader.read_clob()?.as_slice().into())))
261272
}
262273

263274
#[inline]
264-
fn decode_blob(&self, reader: &mut Reader) -> IonDecodeResult {
275+
fn decode_blob(&self, reader: &mut R) -> IonDecodeResult {
265276
Ok(Value::Blob(Box::new(reader.read_blob()?.as_slice().into())))
266277
}
267278

268279
#[inline]
269-
fn decode_list(&self, reader: &mut Reader) -> IonDecodeResult {
280+
fn decode_list(&self, reader: &mut R) -> IonDecodeResult {
270281
decode_list(self, reader)
271282
}
272283

273284
#[inline]
274-
fn decode_sexp(&self, _: &mut Reader) -> IonDecodeResult {
285+
fn decode_sexp(&self, _: &mut R) -> IonDecodeResult {
275286
Err(IonDecodeError::UnsupportedType("sexp"))
276287
}
277288

278289
#[inline]
279-
fn decode_struct(&self, reader: &mut Reader) -> IonDecodeResult {
290+
fn decode_struct(&self, reader: &mut R) -> IonDecodeResult {
280291
decode_struct(self, reader)
281292
}
282293
}
283294

284295
#[inline]
285-
fn decode_list(decoder: &impl IonValueDecoder, reader: &mut Reader) -> IonDecodeResult {
296+
fn decode_list<R>(decoder: &impl IonValueDecoder<R>, reader: &mut R) -> IonDecodeResult
297+
where
298+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
299+
{
286300
reader.step_in()?;
287301
let mut values = vec![];
288302
'values: loop {
@@ -299,18 +313,21 @@ fn decode_list(decoder: &impl IonValueDecoder, reader: &mut Reader) -> IonDecode
299313
}
300314

301315
#[inline]
302-
fn decode_struct(decoder: &impl IonValueDecoder, reader: &mut Reader) -> IonDecodeResult {
316+
fn decode_struct<R>(decoder: &impl IonValueDecoder<R>, reader: &mut R) -> IonDecodeResult
317+
where
318+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
319+
{
303320
let mut tuple = Tuple::new();
304321
reader.step_in()?;
305-
loop {
322+
'kv: loop {
306323
let item = reader.next()?;
307324
let (key, value) = match item {
308325
StreamItem::Value(typ) => {
309326
let field_name = reader.field_name()?;
310327
(field_name, decoder.decode_value(reader, typ)?)
311328
}
312329
StreamItem::Null(_) => (reader.field_name()?, decoder.decode_null(reader)?),
313-
StreamItem::Nothing => break,
330+
StreamItem::Nothing => break 'kv,
314331
};
315332
tuple.insert(key.text_or_error()?, value);
316333
}
@@ -323,7 +340,10 @@ struct PartiqlEncodedIonValueDecoder {
323340
}
324341

325342
#[inline]
326-
fn has_annotation(reader: &Reader, annot: &str) -> bool {
343+
fn has_annotation(
344+
reader: &impl IonReader<Item = StreamItem, Symbol = Symbol>,
345+
annot: &str,
346+
) -> bool {
327347
reader
328348
.annotations()
329349
.any(|a| a.map_or(false, |a| a == annot))
@@ -333,7 +353,10 @@ static TIME_PARTS_PATTERN_SET: Lazy<RegexSet> =
333353
Lazy::new(|| RegexSet::new(RE_SET_TIME_PARTS).unwrap());
334354

335355
impl PartiqlEncodedIonValueDecoder {
336-
fn decode_date(&self, reader: &mut Reader) -> IonDecodeResult {
356+
fn decode_date<R>(&self, reader: &mut R) -> IonDecodeResult
357+
where
358+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
359+
{
337360
let ts = reader.read_timestamp()?;
338361
let datetime = DateTime::from_ymd(
339362
ts.year(),
@@ -345,12 +368,18 @@ impl PartiqlEncodedIonValueDecoder {
345368
Ok(datetime.into())
346369
}
347370

348-
fn decode_time(&self, reader: &mut Reader) -> IonDecodeResult {
349-
fn expect_u8(
350-
reader: &mut Reader,
371+
fn decode_time<R>(&self, reader: &mut R) -> IonDecodeResult
372+
where
373+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
374+
{
375+
fn expect_u8<R>(
376+
reader: &mut R,
351377
typ: Option<IonType>,
352378
unit: &'static str,
353-
) -> Result<u8, IonDecodeError> {
379+
) -> Result<u8, IonDecodeError>
380+
where
381+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
382+
{
354383
match typ {
355384
Some(IonType::Int) => match reader.read_int()? {
356385
Int::I64(i) => Ok(i as u8), // TODO check range
@@ -363,11 +392,14 @@ impl PartiqlEncodedIonValueDecoder {
363392
))),
364393
}
365394
}
366-
fn maybe_i8(
367-
reader: &mut Reader,
395+
fn maybe_i8<R>(
396+
reader: &mut R,
368397
typ: Option<IonType>,
369398
unit: &'static str,
370-
) -> Result<Option<i8>, IonDecodeError> {
399+
) -> Result<Option<i8>, IonDecodeError>
400+
where
401+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
402+
{
371403
match typ {
372404
Some(IonType::Int) => match reader.read_int()? {
373405
Int::I64(i) => Ok(Some(i as i8)), // TODO check range
@@ -382,11 +414,14 @@ impl PartiqlEncodedIonValueDecoder {
382414
))),
383415
}
384416
}
385-
fn expect_f64(
386-
reader: &mut Reader,
417+
fn expect_f64<R>(
418+
reader: &mut R,
387419
typ: Option<IonType>,
388420
unit: &'static str,
389-
) -> Result<f64, IonDecodeError> {
421+
) -> Result<f64, IonDecodeError>
422+
where
423+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
424+
{
390425
match typ {
391426
Some(IonType::Decimal) => {
392427
let dec = ion_decimal_to_decimal(reader.read_decimal()?);
@@ -457,9 +492,12 @@ impl PartiqlEncodedIonValueDecoder {
457492
}
458493
}
459494

460-
impl IonValueDecoder for PartiqlEncodedIonValueDecoder {
495+
impl<R> IonValueDecoder<R> for PartiqlEncodedIonValueDecoder
496+
where
497+
R: IonReader<Item = StreamItem, Symbol = Symbol>,
498+
{
461499
#[inline]
462-
fn decode_null(&self, reader: &mut Reader) -> IonDecodeResult {
500+
fn decode_null(&self, reader: &mut R) -> IonDecodeResult {
463501
if has_annotation(reader, MISSING_ANNOT) {
464502
Ok(Value::Missing)
465503
} else {
@@ -468,7 +506,7 @@ impl IonValueDecoder for PartiqlEncodedIonValueDecoder {
468506
}
469507

470508
#[inline]
471-
fn decode_timestamp(&self, reader: &mut Reader) -> IonDecodeResult {
509+
fn decode_timestamp(&self, reader: &mut R) -> IonDecodeResult {
472510
if has_annotation(reader, DATE_ANNOT) {
473511
self.decode_date(reader)
474512
} else {
@@ -477,7 +515,7 @@ impl IonValueDecoder for PartiqlEncodedIonValueDecoder {
477515
}
478516

479517
#[inline]
480-
fn decode_list(&self, reader: &mut Reader) -> IonDecodeResult {
518+
fn decode_list(&self, reader: &mut R) -> IonDecodeResult {
481519
let is_bag = has_annotation(reader, BAG_ANNOT);
482520
let list = decode_list(self, reader);
483521
if is_bag {
@@ -488,7 +526,7 @@ impl IonValueDecoder for PartiqlEncodedIonValueDecoder {
488526
}
489527

490528
#[inline]
491-
fn decode_struct(&self, reader: &mut Reader) -> IonDecodeResult {
529+
fn decode_struct(&self, reader: &mut R) -> IonDecodeResult {
492530
if has_annotation(reader, TIME_ANNOT) {
493531
self.decode_time(reader)
494532
} else {
@@ -498,15 +536,15 @@ impl IonValueDecoder for PartiqlEncodedIonValueDecoder {
498536

499537
delegate! {
500538
to self.inner {
501-
fn decode_bool(&self, reader: &mut Reader) -> IonDecodeResult;
502-
fn decode_int(&self, reader: &mut Reader) -> IonDecodeResult;
503-
fn decode_float(&self, reader: &mut Reader) -> IonDecodeResult;
504-
fn decode_decimal(&self, reader: &mut Reader) -> IonDecodeResult;
505-
fn decode_symbol(&self, reader: &mut Reader) -> IonDecodeResult;
506-
fn decode_string(&self, reader: &mut Reader) -> IonDecodeResult;
507-
fn decode_clob(&self, reader: &mut Reader) -> IonDecodeResult;
508-
fn decode_blob(&self, reader: &mut Reader) -> IonDecodeResult;
509-
fn decode_sexp(&self, reader: &mut Reader) -> IonDecodeResult;
539+
fn decode_bool(&self, reader: &mut R) -> IonDecodeResult;
540+
fn decode_int(&self, reader: &mut R) -> IonDecodeResult;
541+
fn decode_float(&self, reader: &mut R) -> IonDecodeResult;
542+
fn decode_decimal(&self, reader: &mut R) -> IonDecodeResult;
543+
fn decode_symbol(&self, reader: &mut R) -> IonDecodeResult;
544+
fn decode_string(&self, reader: &mut R) -> IonDecodeResult;
545+
fn decode_clob(&self, reader: &mut R) -> IonDecodeResult;
546+
fn decode_blob(&self, reader: &mut R) -> IonDecodeResult;
547+
fn decode_sexp(&self, reader: &mut R) -> IonDecodeResult;
510548
}
511549
}
512550
}

0 commit comments

Comments
 (0)