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}