ion_rs/
writer.rs

1use crate::raw_symbol_token_ref::AsRawSymbolTokenRef;
2use crate::result::IonResult;
3use crate::types::{Decimal, Int, IonType, Timestamp};
4
5/**
6 * This trait captures the format-agnostic encoding functionality needed to write native Rust types
7 * to a stream as Ion values.
8 */
9pub trait IonWriter {
10    /// The type to which the implementor writes its data. This may be a file, a buffer, etc.
11    type Output;
12
13    /// Returns the (major, minor) version of the Ion stream being written. If ion_version is called
14    /// before an Ion Version Marker has been emitted, the version (1, 0) will be returned.
15    fn ion_version(&self) -> (u8, u8);
16
17    /// Writes an Ion version marker to the output stream.
18    fn write_ion_version_marker(&mut self, major: u8, minor: u8) -> IonResult<()>;
19
20    /// Returns `true` if this RawWriter supports writing field names, annotations, and
21    /// symbol values directly as text; otherwise, returns `false`.
22    ///
23    /// If this method returns `false`, passing a [crate::RawSymbolToken::Text] to the
24    /// [Self::set_annotations], [Self::set_field_name], or [Self::write_symbol] methods may result
25    /// in a panic.
26    fn supports_text_symbol_tokens(&self) -> bool;
27
28    /// Sets a list of annotations that will be applied to the next value that is written.
29    fn set_annotations<I, A>(&mut self, annotations: I)
30    where
31        A: AsRawSymbolTokenRef,
32        I: IntoIterator<Item = A>;
33
34    /// Writes an Ion `null` with the specified type to the output stream.
35    /// To write an untyped `null` (which is equivalent to `null.null`), pass [IonType::Null].
36    fn write_null(&mut self, ion_type: IonType) -> IonResult<()>;
37
38    /// Writes an Ion `boolean` with the specified value to the output stream.
39    fn write_bool(&mut self, value: bool) -> IonResult<()>;
40
41    /// Writes an Ion `integer` with the specified value to the output stream.
42    fn write_i64(&mut self, value: i64) -> IonResult<()>;
43
44    /// Writes an Ion `integer` with the specified value to the output stream.
45    fn write_int(&mut self, value: &Int) -> IonResult<()>;
46
47    /// Writes an Ion `float` with the specified value to the output stream.
48    fn write_f32(&mut self, value: f32) -> IonResult<()>;
49
50    /// Writes an Ion `float` with the specified value to the output stream.
51    fn write_f64(&mut self, value: f64) -> IonResult<()>;
52
53    /// Writes an Ion `decimal` with the specified value to the output stream.
54    fn write_decimal(&mut self, value: &Decimal) -> IonResult<()>;
55
56    /// Writes an Ion `timestamp` with the specified value to the output stream.
57    fn write_timestamp(&mut self, value: &Timestamp) -> IonResult<()>;
58
59    /// Writes an Ion `symbol` with the specified value to the output stream.
60    fn write_symbol<A: AsRawSymbolTokenRef>(&mut self, value: A) -> IonResult<()>;
61
62    /// Writes an Ion `string` with the specified value to the output stream.
63    fn write_string<A: AsRef<str>>(&mut self, value: A) -> IonResult<()>;
64
65    /// Writes an Ion `clob` with the specified value to the output stream.
66    fn write_clob<A: AsRef<[u8]>>(&mut self, value: A) -> IonResult<()>;
67
68    /// Writes an Ion `blob` with the specified value to the output stream.
69    fn write_blob<A: AsRef<[u8]>>(&mut self, value: A) -> IonResult<()>;
70
71    /// Starts a new Ion container with the specified type.
72    /// The only valid IonType values are:
73    /// * [IonType::List]
74    /// * [IonType::SExp]
75    /// * [IonType::Struct]
76    /// Passing any other IonType will result in an `Err`.
77    fn step_in(&mut self, container_type: IonType) -> IonResult<()>;
78
79    /// Sets the current field name to `name`. If the TextWriter is currently positioned inside
80    /// of a struct, the field name will be written before the next value. Otherwise, it will be
81    /// ignored.
82    fn set_field_name<A: AsRawSymbolTokenRef>(&mut self, name: A);
83
84    /// If the writer is positioned at the top level, returns `None`. Otherwise, returns
85    /// `Some(_)` with the parent container's [IonType].
86    fn parent_type(&self) -> Option<IonType>;
87
88    /// Returns the number of containers that the writer has stepped into without subsequently
89    /// stepping out.
90    fn depth(&self) -> usize;
91
92    /// Ends the current container. If the writer is not currently positioned within a container,
93    /// calling this method will result in an `Err`.
94    fn step_out(&mut self) -> IonResult<()>;
95
96    /// Causes any buffered data to be written to the underlying io::Write implementation.
97    /// This method can only be called when the writer is at the top level.
98    fn flush(&mut self) -> IonResult<()>;
99
100    /// Returns a reference to the writer's output.
101    ///
102    /// This method can be used to inspect the Ion data that the writer has produced without having
103    /// to first drop the writer.
104    /// ```
105    /// use ion_rs::element::Element;
106    /// use ion_rs::{IonResult, IonWriter, TextWriter, TextWriterBuilder};
107    /// # fn roundtrip() -> IonResult<()> {
108    /// // Set up our output buffer
109    /// let mut buffer: Vec<u8> = Vec::new();
110    /// // Construct a writer that will serialize values to the buffer
111    /// let mut writer = TextWriterBuilder::default().build(&mut buffer)?;
112    /// // Serialize some data
113    /// writer.write_string("hello")?;
114    /// writer.flush()?;
115    /// // Read the data back from the output buffer
116    /// let output_element = Element::read_one(writer.output())?;
117    /// // Confirm that it matches the input data
118    /// assert_eq!(Element::from("hello"), output_element);
119    /// # Ok(())
120    /// # }
121    /// # roundtrip().unwrap();
122    /// ```
123    fn output(&self) -> &Self::Output;
124
125    /// Returns a mutable reference to the writer's output.
126    ///
127    /// Modifying the underlying sink is an inherently risky operation and can result in unexpected
128    /// behavior or invalid data. It is not recommended for most use cases.
129    fn output_mut(&mut self) -> &mut Self::Output;
130}