Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds LazyRawTextReader support for structs #619

Merged
merged 16 commits into from
Aug 23, 2023
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ num-bigint = "0.4.3"
num-integer = "0.1.44"
num-traits = "0.2"
arrayvec = "0.7"
smallvec = "1.9.0"
smallvec = {version ="1.9.0", features = ["const_generics"]}
digest = { version = "0.9", optional = true }
sha2 = { version = "0.9", optional = true }

Expand Down
6 changes: 3 additions & 3 deletions src/binary/binary_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<W: Write> IonWriter for BinaryWriter<W> {
panic!("Cannot set symbol ID ${symbol_id} as annotation. It is undefined.");
}
}
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text),
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text.as_ref()),
};
self.raw_writer.add_annotation(symbol_id);
}
Expand All @@ -145,7 +145,7 @@ impl<W: Write> IonWriter for BinaryWriter<W> {
));
}
}
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text),
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text.as_ref()),
};
self.raw_writer.write_symbol(symbol_id)
}
Expand All @@ -159,7 +159,7 @@ impl<W: Write> IonWriter for BinaryWriter<W> {
panic!("Cannot set symbol ID ${symbol_id} as field name. It is undefined.");
}
}
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text),
RawSymbolTokenRef::Text(text) => self.get_or_create_symbol_id(text.as_ref()),
};
self.raw_writer.set_field_name(text);
}
Expand Down
19 changes: 0 additions & 19 deletions src/lazy/binary/encoding.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/lazy/binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ mod encoded_value;
pub mod immutable_buffer;
pub mod raw;

pub(crate) mod encoding;
#[cfg(test)]
pub(crate) mod test_utilities;
2 changes: 1 addition & 1 deletion src/lazy/binary/raw/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod annotations_iterator;
pub mod lazy_raw_sequence;
pub mod reader;
pub mod sequence;
pub mod r#struct;
pub mod value;
2 changes: 1 addition & 1 deletion src/lazy/binary/raw/reader.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::lazy::binary::encoding::BinaryEncoding;
use crate::lazy::binary::immutable_buffer::ImmutableBuffer;
use crate::lazy::binary::raw::value::LazyRawBinaryValue;
use crate::lazy::decoder::LazyRawReader;
use crate::lazy::encoding::BinaryEncoding;
use crate::lazy::raw_stream_item::RawStreamItem;
use crate::result::IonFailure;
use crate::IonResult;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::lazy::binary::encoding::BinaryEncoding;
use crate::lazy::binary::immutable_buffer::ImmutableBuffer;
use crate::lazy::binary::raw::annotations_iterator::RawBinaryAnnotationsIterator;
use crate::lazy::binary::raw::reader::DataSource;
use crate::lazy::binary::raw::value::LazyRawBinaryValue;
use crate::lazy::decoder::private::LazyContainerPrivate;
use crate::lazy::decoder::LazyRawSequence;
use crate::lazy::encoding::BinaryEncoding;
use crate::{IonResult, IonType};
use std::fmt;
use std::fmt::{Debug, Formatter};
Expand All @@ -18,11 +18,11 @@ impl<'data> LazyRawBinarySequence<'data> {
self.value.ion_type()
}

pub fn iter(&self) -> RawSequenceIterator<'data> {
pub fn iter(&self) -> RawBinarySequenceIterator<'data> {
// Get as much of the sequence's body as is available in the input buffer.
// Reading a child value may fail as `Incomplete`
let buffer_slice = self.value.available_body();
RawSequenceIterator::new(buffer_slice)
RawBinarySequenceIterator::new(buffer_slice)
}
}

Expand All @@ -33,7 +33,7 @@ impl<'data> LazyContainerPrivate<'data, BinaryEncoding> for LazyRawBinarySequenc
}

impl<'data> LazyRawSequence<'data, BinaryEncoding> for LazyRawBinarySequence<'data> {
type Iterator = RawSequenceIterator<'data>;
type Iterator = RawBinarySequenceIterator<'data>;

fn annotations(&self) -> RawBinaryAnnotationsIterator<'data> {
self.value.annotations()
Expand All @@ -54,7 +54,7 @@ impl<'data> LazyRawSequence<'data, BinaryEncoding> for LazyRawBinarySequence<'da

impl<'a, 'data> IntoIterator for &'a LazyRawBinarySequence<'data> {
type Item = IonResult<LazyRawBinaryValue<'data>>;
type IntoIter = RawSequenceIterator<'data>;
type IntoIter = RawBinarySequenceIterator<'data>;

fn into_iter(self) -> Self::IntoIter {
self.iter()
Expand Down Expand Up @@ -99,19 +99,19 @@ impl<'a> Debug for LazyRawBinarySequence<'a> {
}
}

pub struct RawSequenceIterator<'data> {
pub struct RawBinarySequenceIterator<'data> {
source: DataSource<'data>,
}

impl<'data> RawSequenceIterator<'data> {
pub(crate) fn new(input: ImmutableBuffer<'data>) -> RawSequenceIterator<'data> {
RawSequenceIterator {
impl<'data> RawBinarySequenceIterator<'data> {
pub(crate) fn new(input: ImmutableBuffer<'data>) -> RawBinarySequenceIterator<'data> {
RawBinarySequenceIterator {
source: DataSource::new(input),
}
}
}

impl<'data> Iterator for RawSequenceIterator<'data> {
impl<'data> Iterator for RawBinarySequenceIterator<'data> {
type Item = IonResult<LazyRawBinaryValue<'data>>;

fn next(&mut self) -> Option<Self::Item> {
Expand Down
2 changes: 1 addition & 1 deletion src/lazy/binary/raw/struct.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::lazy::binary::encoding::BinaryEncoding;
use crate::lazy::binary::immutable_buffer::ImmutableBuffer;
use crate::lazy::binary::raw::annotations_iterator::RawBinaryAnnotationsIterator;
use crate::lazy::binary::raw::reader::DataSource;
use crate::lazy::binary::raw::value::LazyRawBinaryValue;
use crate::lazy::decoder::private::{LazyContainerPrivate, LazyRawFieldPrivate};
use crate::lazy::decoder::{LazyRawField, LazyRawStruct};
use crate::lazy::encoding::BinaryEncoding;
use crate::lazy::raw_value_ref::RawValueRef;
use crate::raw_symbol_token_ref::AsRawSymbolTokenRef;
use crate::{IonResult, RawSymbolTokenRef};
Expand Down
19 changes: 14 additions & 5 deletions src/lazy/binary/raw/value.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::binary::int::DecodedInt;
use crate::binary::uint::DecodedUInt;
use crate::lazy::binary::encoded_value::EncodedValue;
use crate::lazy::binary::encoding::BinaryEncoding;
use crate::lazy::binary::immutable_buffer::ImmutableBuffer;
use crate::lazy::binary::raw::annotations_iterator::RawBinaryAnnotationsIterator;
use crate::lazy::binary::raw::lazy_raw_sequence::LazyRawBinarySequence;
use crate::lazy::binary::raw::r#struct::LazyRawBinaryStruct;
use crate::lazy::binary::raw::sequence::LazyRawBinarySequence;
use crate::lazy::decoder::private::LazyRawValuePrivate;
use crate::lazy::decoder::LazyRawValue;
use crate::lazy::encoding::BinaryEncoding;
use crate::lazy::raw_value_ref::RawValueRef;
use crate::lazy::str_ref::StrRef;
use crate::result::IonFailure;
use crate::types::SymbolId;
use crate::{Decimal, Int, IonError, IonResult, IonType, RawSymbolTokenRef, Timestamp};
Expand All @@ -35,7 +36,7 @@ impl<'a> Debug for LazyRawBinaryValue<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"LazyRawValue {{\n val={:?},\n buf={:?}\n}}\n",
"LazyRawBinaryValue {{\n val={:?},\n buf={:?}\n}}\n",
self.encoded_value, self.input
)
}
Expand All @@ -54,6 +55,10 @@ impl<'data> LazyRawValue<'data, BinaryEncoding> for LazyRawBinaryValue<'data> {
self.ion_type()
}

fn is_null(&self) -> bool {
self.is_null()
}

fn annotations(&self) -> RawBinaryAnnotationsIterator<'data> {
self.annotations()
}
Expand All @@ -70,6 +75,10 @@ impl<'data> LazyRawBinaryValue<'data> {
self.encoded_value.ion_type()
}

pub fn is_null(&self) -> bool {
self.encoded_value.header().is_null()
}

/// Returns `true` if this value has a non-empty annotations sequence; otherwise, returns `false`.
fn has_annotations(&self) -> bool {
self.encoded_value.has_annotations()
Expand Down Expand Up @@ -118,7 +127,7 @@ impl<'data> LazyRawBinaryValue<'data> {
/// [`LazyRawBinarySequence`] or [`LazyStruct`](crate::lazy::struct::LazyStruct)
/// that can be traversed to access the container's contents.
pub fn read(&self) -> ValueParseResult<'data, BinaryEncoding> {
if self.encoded_value.header().is_null() {
if self.is_null() {
let raw_value_ref = RawValueRef::Null(self.ion_type());
return Ok(raw_value_ref);
}
Expand Down Expand Up @@ -382,7 +391,7 @@ impl<'data> LazyRawBinaryValue<'data> {
let raw_bytes = self.value_body()?;
let text = std::str::from_utf8(raw_bytes)
.map_err(|_| IonError::decoding_error("found a string with invalid utf-8 data"))?;
Ok(RawValueRef::String(text))
Ok(RawValueRef::String(StrRef::from(text)))
}

/// Helper method called by [`Self::read`]. Reads the current value as a blob.
Expand Down
9 changes: 9 additions & 0 deletions src/lazy/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::lazy::raw_stream_item::RawStreamItem;
use crate::lazy::raw_value_ref::RawValueRef;
use crate::result::IonFailure;
use crate::{IonResult, IonType, RawSymbolTokenRef};
use std::fmt::Debug;

Expand Down Expand Up @@ -62,6 +63,7 @@ pub trait LazyRawValue<'data, D: LazyDecoder<'data>>:
private::LazyRawValuePrivate<'data> + Clone + Debug
{
fn ion_type(&self) -> IonType;
fn is_null(&self) -> bool;
fn annotations(&self) -> D::AnnotationsIterator;
fn read(&self) -> IonResult<RawValueRef<'data, D>>;
}
Expand All @@ -85,6 +87,13 @@ pub trait LazyRawStruct<'data, D: LazyDecoder<'data>>:
fn annotations(&self) -> D::AnnotationsIterator;
fn find(&self, name: &str) -> IonResult<Option<D::Value>>;
fn get(&self, name: &str) -> IonResult<Option<RawValueRef<'data, D>>>;
fn get_expected(&self, name: &str) -> IonResult<RawValueRef<'data, D>> {
if let Some(value) = self.get(name)? {
Ok(value)
} else {
IonResult::decoding_error(format!("did not find expected struct field '{}'", name))
}
}
fn iter(&self) -> Self::Iterator;
}

Expand Down
57 changes: 57 additions & 0 deletions src/lazy/encoding.rs
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗺️ This file housed lots of ToDo* types that existed to satisfy the LazyDecoder trait. This PR replaces them with actual implementations.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::marker::PhantomData;

use crate::lazy::binary::raw::annotations_iterator::RawBinaryAnnotationsIterator;
use crate::lazy::binary::raw::r#struct::LazyRawBinaryStruct;
use crate::lazy::binary::raw::reader::LazyRawBinaryReader;
use crate::lazy::binary::raw::sequence::LazyRawBinarySequence;
use crate::lazy::binary::raw::value::LazyRawBinaryValue;
use crate::lazy::decoder::LazyDecoder;
use crate::lazy::text::raw::r#struct::LazyRawTextStruct;
use crate::lazy::text::raw::reader::LazyRawTextReader;
use crate::lazy::text::raw::sequence::LazyRawTextSequence;
use crate::lazy::text::value::LazyRawTextValue;
use crate::{IonResult, RawSymbolTokenRef};

// These types derive trait implementations in order to allow types that containing them
// to also derive trait implementations.

/// The Ion 1.0 binary encoding.
#[derive(Clone, Debug)]
pub struct BinaryEncoding;

/// The Ion 1.0 text encoding.
#[derive(Clone, Debug)]
pub struct TextEncoding;

impl<'data> LazyDecoder<'data> for BinaryEncoding {
type Reader = LazyRawBinaryReader<'data>;
type Value = LazyRawBinaryValue<'data>;
type Sequence = LazyRawBinarySequence<'data>;
type Struct = LazyRawBinaryStruct<'data>;
type AnnotationsIterator = RawBinaryAnnotationsIterator<'data>;
}

// === Placeholders ===
// The types below will need to be properly defined in order for the lazy text reader to be complete.
// The exist to satisfy various trait definitions.

#[derive(Debug, Clone)]
pub struct ToDoTextAnnotationsIterator<'data> {
spooky: &'data PhantomData<()>,
}

impl<'data> Iterator for ToDoTextAnnotationsIterator<'data> {
type Item = IonResult<RawSymbolTokenRef<'data>>;

fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}

impl<'data> LazyDecoder<'data> for TextEncoding {
type Reader = LazyRawTextReader<'data>;
type Value = LazyRawTextValue<'data>;
type Sequence = LazyRawTextSequence<'data>;
type Struct = LazyRawTextStruct<'data>;
type AnnotationsIterator = ToDoTextAnnotationsIterator<'data>;
}
3 changes: 3 additions & 0 deletions src/lazy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@

pub mod binary;
pub mod decoder;
pub(crate) mod encoding;
pub mod raw_stream_item;
pub mod raw_value_ref;
pub mod reader;
pub mod sequence;
pub mod str_ref;
pub mod r#struct;
pub mod system_reader;
pub mod system_stream_item;
pub mod text;
pub mod value;
pub mod value_ref;