ion_rs/
stream_reader.rs

1use crate::element::{Blob, Clob};
2use crate::result::IonResult;
3use crate::types::{Decimal, Int, IonType, Str, Timestamp};
4
5/**
6 * This trait captures the format-agnostic parser functionality needed to navigate within an Ion
7 * stream and read the values encountered into native Rust data types.
8 *
9 * Once a value has successfully been read from the stream using one of the read_* functions,
10 * calling that function again may return an Err. This is left to the discretion of the implementor.
11 */
12pub trait IonReader {
13    /// The type returned by calls to [Self::next], indicating the next entity in the stream.
14    /// Reader implementations representing different levels of abstraction will surface
15    /// different sets of encoding artifacts. While an application-level Reader would only surface
16    /// Ion values, a lower level Reader might surface symbol tables, Ion version markers, etc.
17    type Item;
18
19    /// The types used to represent field names, annotations, and symbol values at this Reader's
20    /// level of abstraction.
21    type Symbol;
22
23    /// Returns the (major, minor) version of the Ion stream being read. If ion_version is called
24    /// before an Ion Version Marker has been read, the version (1, 0) will be returned.
25    fn ion_version(&self) -> (u8, u8);
26
27    /// Attempts to advance the cursor to the next value in the stream at the current depth.
28    /// If no value is encountered, returns None; otherwise, returns the Ion type of the next value.
29    fn next(&mut self) -> IonResult<Self::Item>;
30
31    /// Returns a value describing the stream entity over which the Reader is currently positioned.
32    /// Depending on the Reader's level of abstraction, that entity may or may not be an Ion value.
33    fn current(&self) -> Self::Item;
34
35    /// If the current item is a value, returns that value's Ion type. Otherwise, returns None.
36    fn ion_type(&self) -> Option<IonType>;
37
38    /// Returns an iterator that will yield each of the annotations for the current value in order.
39    /// If there is no current value, returns an empty iterator.
40    // TODO: When GATs are stabilized, we can change this to a known associated type that's generic
41    //       over the lifetime of &self.
42    fn annotations<'a>(&'a self) -> Box<dyn Iterator<Item = IonResult<Self::Symbol>> + 'a>;
43
44    /// If the reader is positioned over a value with one or more annotations, returns `true`.
45    /// Otherwise, returns `false`.
46    fn has_annotations(&self) -> bool {
47        // Implementations are encouraged to override this when there's a cheaper way of
48        // determining whether the current value has annotations.
49        self.annotations().next().is_some()
50    }
51
52    /// Returns the number of annotations on the current value. If there is no current value,
53    /// returns zero.
54    fn number_of_annotations(&self) -> usize {
55        // Implementations are encouraged to override this when there's a cheaper way of
56        // calculating the number of annotations.
57        self.annotations().count()
58    }
59
60    /// If the current item is a field within a struct, returns `Ok(_)` with a [Self::Symbol]
61    /// representing the field's name; otherwise, returns an [crate::IonError::IllegalOperation].
62    ///
63    /// Implementations may also return an error for other reasons; for example, if [Self::Symbol]
64    /// is a text data type but the field name is an undefined symbol ID, the reader may return
65    /// a decoding error.
66    fn field_name(&self) -> IonResult<Self::Symbol>;
67
68    /// Returns `true` if the reader is currently positioned over an Ion null of any type.
69    fn is_null(&self) -> bool;
70
71    /// Attempts to read the current item as an Ion null and return its Ion type. If the current
72    /// item is not a null or an IO error is encountered while reading, returns [crate::IonError].
73    fn read_null(&mut self) -> IonResult<IonType>;
74
75    /// Attempts to read the current item as an Ion boolean and return it as a bool. If the current
76    /// item is not a boolean or an IO error is encountered while reading, returns [crate::IonError].
77    fn read_bool(&mut self) -> IonResult<bool>;
78
79    /// Attempts to read the current item as an Ion integer and return it as an i64. If the current
80    /// item is not an integer, the integer is too large to be represented as an `i64`, or an IO
81    /// error is encountered while reading, returns [crate::IonError].
82    fn read_i64(&mut self) -> IonResult<i64>;
83
84    /// Attempts to read the current item as an Ion integer and return it as an [`Int`](crate::types::Int). If the
85    /// current item is not an integer or an IO error is encountered while reading, returns
86    /// [crate::IonError].
87    fn read_int(&mut self) -> IonResult<Int>;
88
89    /// Attempts to read the current item as an Ion float and return it as an f32. If the current
90    /// item is not a float or an IO error is encountered while reading, returns [crate::IonError].
91    fn read_f32(&mut self) -> IonResult<f32>;
92
93    /// Attempts to read the current item as an Ion float and return it as an f64. If the current
94    /// item is not a float or an IO error is encountered while reading, returns [crate::IonError].
95    fn read_f64(&mut self) -> IonResult<f64>;
96
97    /// Attempts to read the current item as an Ion decimal and return it as a [crate::Decimal]. If the current
98    /// item is not a decimal or an IO error is encountered while reading, returns [crate::IonError].
99    fn read_decimal(&mut self) -> IonResult<Decimal>;
100
101    /// Attempts to read the current item as an Ion string and return it as a [String]. If the current
102    /// item is not a string or an IO error is encountered while reading, returns [crate::IonError].
103    fn read_string(&mut self) -> IonResult<Str>;
104
105    /// Attempts to read the current item as an Ion string and return it as a [&str]. If the
106    /// current item is not a string or an IO error is encountered while reading, returns
107    /// [crate::IonError].
108    fn read_str(&mut self) -> IonResult<&str>;
109
110    /// Attempts to read the current item as an Ion symbol and return it as a [Self::Symbol]. If the
111    /// current item is not a symbol or an IO error is encountered while reading, returns [crate::IonError].
112    fn read_symbol(&mut self) -> IonResult<Self::Symbol>;
113
114    /// Attempts to read the current item as an Ion blob and return it as a `Vec<u8>`. If the
115    /// current item is not a blob or an IO error is encountered while reading, returns [crate::IonError].
116    fn read_blob(&mut self) -> IonResult<Blob>;
117
118    /// Attempts to read the current item as an Ion clob and return it as a `Vec<u8>`. If the
119    /// current item is not a clob or an IO error is encountered while reading, returns [crate::IonError].
120    fn read_clob(&mut self) -> IonResult<Clob>;
121
122    /// Attempts to read the current item as an Ion timestamp and return [crate::Timestamp]. If the current
123    /// item is not a timestamp or an IO error is encountered while reading, returns [crate::IonError].
124    fn read_timestamp(&mut self) -> IonResult<Timestamp>;
125
126    /// If the current value is a container (i.e. a struct, list, or s-expression), positions the
127    /// cursor at the beginning of that container's sequence of child values. The application must
128    /// call [Self::next()] to advance to the first child value. If the current value is not a container,
129    /// returns [crate::IonError].
130    fn step_in(&mut self) -> IonResult<()>;
131
132    /// Positions the cursor at the end of the container currently being traversed. Calling [Self::next()]
133    /// will position the cursor over the item that follows the container. If the cursor is not in
134    /// a container (i.e. it is already at the top level), returns [crate::IonError].
135    fn step_out(&mut self) -> IonResult<()>;
136
137    /// If the reader is positioned at the top level, returns `None`. Otherwise, returns
138    /// `Some(_)` with the parent container's [crate::IonType].
139    fn parent_type(&self) -> Option<IonType>;
140
141    /// Returns a [usize] indicating the Reader's current level of nesting. That is: the number of
142    /// times the Reader has stepped into a container without later stepping out. At the top level,
143    /// this method returns `0`.
144    fn depth(&self) -> usize;
145}