ion_rs/
raw_reader.rs

1use crate::element::{Blob, Clob};
2use crate::raw_symbol_token::RawSymbolToken;
3use crate::stream_reader::IonReader;
4use crate::types::{IonType, Str};
5use crate::{Decimal, Int, IonResult, Timestamp};
6use std::fmt::{Display, Formatter};
7use std::io::Read;
8
9/// `RawReader` is a shorthand for a [Reader](crate::Reader) implementation that returns [RawStreamItem]s and
10/// uses [RawSymbolToken] to represent its field names, annotations, and symbol values.
11pub trait RawReader: IonReader<Item = RawStreamItem, Symbol = RawSymbolToken> {}
12
13impl<T> RawReader for T where T: IonReader<Item = RawStreamItem, Symbol = RawSymbolToken> {}
14
15/// Allows a `Box<dyn RawReader>` to be used as a RawReader.
16/// Note: this implementation contains some methods that are not object safe and so cannot be
17///       invoked. For the moment, calling these methods via dynamic dispatch will result in a
18///       panic. Longer-term, they will be replaced by object safe methods.
19///       See: <https://github.com/amazon-ion/ion-rust/issues/335>
20impl<R: RawReader + ?Sized> IonReader for Box<R> {
21    type Item = RawStreamItem;
22    type Symbol = RawSymbolToken;
23
24    #[inline]
25    fn ion_version(&self) -> (u8, u8) {
26        (**self).ion_version()
27    }
28
29    fn next(&mut self) -> IonResult<Self::Item> {
30        (**self).next()
31    }
32
33    fn current(&self) -> Self::Item {
34        (**self).current()
35    }
36
37    fn ion_type(&self) -> Option<IonType> {
38        (**self).ion_type()
39    }
40
41    fn annotations<'a>(&'a self) -> Box<dyn Iterator<Item = IonResult<Self::Symbol>> + 'a> {
42        (**self).annotations()
43    }
44
45    fn field_name(&self) -> IonResult<Self::Symbol> {
46        (**self).field_name()
47    }
48
49    fn is_null(&self) -> bool {
50        (**self).is_null()
51    }
52
53    fn read_null(&mut self) -> IonResult<IonType> {
54        (**self).read_null()
55    }
56
57    fn read_bool(&mut self) -> IonResult<bool> {
58        (**self).read_bool()
59    }
60
61    fn read_i64(&mut self) -> IonResult<i64> {
62        (**self).read_i64()
63    }
64
65    fn read_int(&mut self) -> IonResult<Int> {
66        (**self).read_int()
67    }
68
69    fn read_f32(&mut self) -> IonResult<f32> {
70        (**self).read_f32()
71    }
72
73    fn read_f64(&mut self) -> IonResult<f64> {
74        (**self).read_f64()
75    }
76
77    fn read_decimal(&mut self) -> IonResult<Decimal> {
78        (**self).read_decimal()
79    }
80
81    fn read_string(&mut self) -> IonResult<Str> {
82        (**self).read_string()
83    }
84
85    fn read_str(&mut self) -> IonResult<&str> {
86        (**self).read_str()
87    }
88
89    fn read_symbol(&mut self) -> IonResult<Self::Symbol> {
90        (**self).read_symbol()
91    }
92
93    fn read_blob(&mut self) -> IonResult<Blob> {
94        (**self).read_blob()
95    }
96
97    fn read_clob(&mut self) -> IonResult<Clob> {
98        (**self).read_clob()
99    }
100
101    fn read_timestamp(&mut self) -> IonResult<Timestamp> {
102        (**self).read_timestamp()
103    }
104
105    fn step_in(&mut self) -> IonResult<()> {
106        (**self).step_in()
107    }
108
109    fn step_out(&mut self) -> IonResult<()> {
110        (**self).step_out()
111    }
112
113    fn parent_type(&self) -> Option<IonType> {
114        (**self).parent_type()
115    }
116
117    fn depth(&self) -> usize {
118        (**self).depth()
119    }
120}
121
122#[derive(Debug, Eq, PartialEq, Copy, Clone)]
123/// Raw stream components that a RawReader may encounter.
124pub enum RawStreamItem {
125    /// An Ion Version Marker (IVM) indicating the Ion major and minor version that were used to
126    /// encode the values that follow.
127    VersionMarker(u8, u8),
128    /// A non-null Ion value and its corresponding Ion data type.
129    /// Stream values that represent system constructs (e.g. a struct marked with a
130    /// $ion_symbol_table annotation) are still considered values at the raw level.
131    Value(IonType),
132    /// A null Ion value and its corresponding Ion data type.
133    Null(IonType),
134    /// Indicates that the reader is not positioned over anything. This can happen:
135    /// * before the reader has begun processing the stream.
136    /// * after the reader has stepped into a container, but before the reader has called next()
137    /// * after the reader has stepped out of a container, but before the reader has called next()
138    /// * after the reader has read the last item in a container
139    Nothing,
140}
141
142impl RawStreamItem {
143    /// If `is_null` is `true`, returns `RawStreamItem::Value(ion_type)`. Otherwise,
144    /// returns `RawStreamItem::Null(ion_type)`.
145    pub fn nullable_value(ion_type: IonType, is_null: bool) -> RawStreamItem {
146        if is_null {
147            RawStreamItem::Null(ion_type)
148        } else {
149            RawStreamItem::Value(ion_type)
150        }
151    }
152}
153
154impl Display for RawStreamItem {
155    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
156        use RawStreamItem::*;
157        match self {
158            VersionMarker(major, minor) => write!(f, "ion version marker (v{major}.{minor})"),
159            Value(ion_type) => write!(f, "{ion_type}"),
160            Null(ion_type) => write!(f, "null.{ion_type}"),
161            Nothing => write!(f, "nothing/end-of-sequence"),
162        }
163    }
164}
165
166/// BufferedRawReader is a RawReader which can be created from a [`Vec<u8>`] and implements the needed
167/// functionality to provide non-blocking reader support. This includes the ability to add more
168/// data as needed, as well as marking when the stream is complete.
169pub trait BufferedRawReader: RawReader + From<Vec<u8>> {
170    fn append_bytes(&mut self, bytes: &[u8]) -> IonResult<()>;
171    fn read_from<R: Read>(&mut self, source: R, length: usize) -> IonResult<usize>;
172    // Mark the stream as complete. This allows the reader to understand when partial parses on
173    // data boundaries are not possible.
174    fn stream_complete(&mut self);
175    fn is_stream_complete(&self) -> bool;
176}
177
178/// Provides a mechanism for identifying input types that allow adding more data.
179/// This allows for some input-type oriented behaviors, like initializing the end of stream status
180/// to true if we know more data can not be added.
181pub trait Expandable {
182    fn expandable(&self) -> bool;
183}
184
185impl<T: AsRef<[u8]> + ?Sized> Expandable for &T {
186    fn expandable(&self) -> bool {
187        false
188    }
189}
190
191impl Expandable for Vec<u8> {
192    fn expandable(&self) -> bool {
193        true
194    }
195}