Skip to content

Commit

Permalink
Null stream item (#370)
Browse files Browse the repository at this point in the history
* Split `Value` stream items into `Value` and `Null`

Each implementation of `StreamReader` has an associated type called
`Item` that represents the set of possible entities that the reader may
encounter in its stream:

| Reader       |      Item        |
|--------------|------------------|
| RawReader    | RawStreamItem    |
| SystemReader | SystemStreamItem |
| Reader       | StreamItem       |

While the entities enumerated by `Item` vary according to the reader's
level of abstraction, all of them include a `Value` variant that
indicates that the reader is currently positioned over an Ion value.

Prior to this PR, each `Value` enum variant was modeled as:

      Value(IonType, bool)

in which the `IonType` represented the value's corresponding Ion data
type and the `bool` indicated whether the value was a `null`. This
lead to user code that looked like:

```rust
     match reader.next()? {
        Value(IonType::String, true)  => /* ... */,
        Value(IonType::String, false) => /* ... */,
        _ => {}
     }
```

In such situations, the meaning of the `true` or `false` was not
obvious.

This PR splits `Value(IonType, bool)` out into two variants for
each enum:

```rust
enum $NAME {
     // ...
     Value(IonType),
     Null(IonType),
     // ...
}
````

This makes most interactions with the enum both more self-documenting
and more concise.

This PR also modifies `Reader` and `SymbolTable` to be able to handle
non-`string` values in a local symbol table.

Fixes #368.
  • Loading branch information
zslayton authored Apr 29, 2022
1 parent 935e306 commit 028cce7
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 262 deletions.
11 changes: 6 additions & 5 deletions examples/read_all_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@ fn main() -> IonResult<()> {
// Prints the total number of values read upon completion.
fn read_all_values<R: IonDataSource>(cursor: &mut RawBinaryReader<R>) -> IonResult<usize> {
use IonType::*;
use RawStreamItem::*;
use RawStreamItem::{Nothing, Null as NullValue, Value, VersionMarker};
let mut count: usize = 0;
loop {
match cursor.next()? {
VersionMarker(_major, _minor) => {}
Value(ion_type, is_null) => {
NullValue(_ion_type) => {
count += 1;
continue;
}
Value(ion_type) => {
count += 1;
if is_null {
continue;
}
match ion_type {
Struct | List | SExpression => cursor.step_in()?,
String => {
Expand Down
12 changes: 6 additions & 6 deletions src/binary/binary_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ mod tests {
binary_writer.flush()?;

let mut reader = Reader::new(RawBinaryReader::new(io::Cursor::new(buffer)));
assert_eq!(Value(IonType::Struct, false), reader.next()?);
assert_eq!(Value(IonType::Struct), reader.next()?);
reader.step_in()?;
assert_eq!(Value(IonType::Symbol, false), reader.next()?);
assert_eq!(Value(IonType::Symbol), reader.next()?);
assert_eq!("foo", reader.field_name()?);
assert_eq!("bar", reader.read_symbol()?.as_ref());

Expand All @@ -228,7 +228,7 @@ mod tests {
binary_writer.flush()?;

let mut reader = Reader::new(RawBinaryReader::new(io::Cursor::new(buffer)));
assert_eq!(Value(IonType::Integer, false), reader.next()?);
assert_eq!(Value(IonType::Integer), reader.next()?);
let mut annotations = reader.annotations();
assert_eq!("foo", annotations.next().unwrap()?);
assert_eq!("bar", annotations.next().unwrap()?);
Expand All @@ -247,11 +247,11 @@ mod tests {
binary_writer.flush()?;

let mut reader = Reader::new(RawBinaryReader::new(io::Cursor::new(buffer)));
assert_eq!(Value(IonType::Symbol, false), reader.next()?);
assert_eq!(Value(IonType::Symbol), reader.next()?);
assert_eq!("foo", reader.read_symbol()?);
assert_eq!(Value(IonType::Symbol, false), reader.next()?);
assert_eq!(Value(IonType::Symbol), reader.next()?);
assert_eq!("bar", reader.read_symbol()?);
assert_eq!(Value(IonType::Symbol, false), reader.next()?);
assert_eq!(Value(IonType::Symbol), reader.next()?);
assert_eq!("baz", reader.read_symbol()?);

Ok(())
Expand Down
Loading

0 comments on commit 028cce7

Please sign in to comment.