Skip to main content

ion_rs/element/
sequence.rs

1use crate::element::builders::SequenceBuilder;
2use crate::element::iterators::SequenceIterator;
3use crate::element::Element;
4use crate::ion_data::{IonDataHash, IonDataOrd, IonEq};
5use crate::lazy::encoding::Encoding;
6use crate::write_config::WriteConfig;
7use crate::IonResult;
8use std::cmp::Ordering;
9use std::collections::VecDeque;
10use std::fmt::{Debug, Formatter};
11use std::hash::Hasher;
12use std::io;
13
14/// An iterable, addressable series of Ion [`Element`]s.
15///
16/// A `Sequence` is not itself an Ion value type, but can represent a series of Ion values appearing
17/// in a [`List`](crate::List), a [`SExp`](crate::SExp), or at the top level.
18#[derive(Clone, PartialEq)]
19pub struct Sequence {
20    elements: Vec<Element>,
21}
22
23impl Debug for Sequence {
24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25        write!(f, "Sequence<")?;
26        let mut is_first = true;
27        for element in self {
28            if is_first {
29                write!(f, "{element}")?;
30                is_first = false;
31            } else {
32                write!(f, ", {element}")?;
33            }
34        }
35        write!(f, ">")
36    }
37}
38
39impl Sequence {
40    pub fn new<E: Into<Element>, I: IntoIterator<Item = E>>(elements: I) -> Sequence {
41        let elements = elements.into_iter().map(|e| e.into()).collect();
42        Sequence { elements }
43    }
44
45    pub fn builder() -> SequenceBuilder {
46        SequenceBuilder::new()
47    }
48
49    pub fn clone_builder(&self) -> SequenceBuilder {
50        SequenceBuilder::with_initial_elements(&self.elements)
51    }
52
53    pub fn elements(&self) -> SequenceIterator<'_> {
54        SequenceIterator::new(&self.elements)
55    }
56
57    pub fn get(&self, index: usize) -> Option<&Element> {
58        self.elements.get(index)
59    }
60
61    pub fn len(&self) -> usize {
62        self.elements.len()
63    }
64
65    pub fn is_empty(&self) -> bool {
66        self.len() == 0
67    }
68
69    pub fn iter(&self) -> SequenceIterator<'_> {
70        self.elements()
71    }
72
73    /// ```
74    ///# use ion_rs::IonResult;
75    ///# fn main() -> IonResult<()> {
76    /// use ion_rs::{Element, Sequence};
77    /// use ion_rs::v1_0::Binary;
78    ///
79    /// let ion_data = r#"1 2 3 foo bar baz"#;
80    /// let sequence_before: Sequence = Element::read_all(ion_data)?;
81    ///
82    /// // Encode the elements in this sequence as a binary Ion stream.
83    /// let ion_bytes: Vec<u8> = sequence_before.encode_as(Binary)?;
84    /// // Read the sequence back from the binary stream
85    /// let sequence_after = Element::read_all(ion_bytes)?;
86    ///
87    /// // Confirm that the value we read back is identical to the one we serialized
88    /// assert_eq!(sequence_before, sequence_after);
89    ///
90    ///# Ok(())
91    ///# }
92    /// ```
93    pub fn encode_as<E: Encoding, C: Into<WriteConfig<E>>>(
94        &self,
95        config: C,
96    ) -> IonResult<E::Output> {
97        config.into().encode_all(self.elements())
98    }
99
100    /// ```
101    ///# use ion_rs::IonResult;
102    ///# fn main() -> IonResult<()> {
103    /// use ion_rs::{Element, Sequence};
104    /// use ion_rs::v1_0::Binary;
105    ///
106    /// let ion_data = r#"1 2 3 foo bar baz"#;
107    /// let sequence_before: Sequence = Element::read_all(ion_data)?;
108    ///
109    /// // Encode the elements in this sequence to our buffer as a binary Ion stream. The bytes will
110    /// // be written to the provided Vec<u8>, and the Vec<u8> will be returned when encoding is complete.
111    /// let ion_bytes: Vec<u8> = sequence_before.encode_to(Vec::new(), Binary)?;
112    /// // Read the sequence back from the binary stream
113    /// let sequence_after = Element::read_all(ion_bytes)?;
114    ///
115    /// // Confirm that the value we read back is identical to the one we serialized
116    /// assert_eq!(sequence_before, sequence_after);
117    ///
118    ///# Ok(())
119    ///# }
120    /// ```
121    pub fn encode_to<E: Encoding, C: Into<WriteConfig<E>>, W: io::Write>(
122        &self,
123        output: W,
124        config: C,
125    ) -> IonResult<W> {
126        config.into().encode_all_to(output, self.elements())
127    }
128}
129
130impl AsRef<Sequence> for Sequence {
131    fn as_ref(&self) -> &Sequence {
132        self
133    }
134}
135
136impl AsRef<[Element]> for Sequence {
137    fn as_ref(&self) -> &[Element] {
138        self.elements.as_slice()
139    }
140}
141
142impl From<Sequence> for Vec<Element> {
143    fn from(value: Sequence) -> Self {
144        value.elements
145    }
146}
147
148// This is more efficient than Sequence::new(), which will iterate over and convert each value to
149// an Element for better ergonomics.
150impl From<Vec<Element>> for Sequence {
151    fn from(elements: Vec<Element>) -> Self {
152        Sequence { elements }
153    }
154}
155
156impl<'a> IntoIterator for &'a Sequence {
157    type Item = &'a Element;
158    // TODO: Change once `impl Trait` type aliases are stable
159    // type IntoIter = impl Iterator<Item = &'a Element>;
160    type IntoIter = SequenceIterator<'a>;
161
162    fn into_iter(self) -> Self::IntoIter {
163        self.elements()
164    }
165}
166
167impl IntoIterator for Sequence {
168    type Item = Element;
169    // TODO: Change once `impl Trait` type aliases are stable
170    // type IntoIter = impl Iterator<Item = &'a Element>;
171    type IntoIter = OwnedSequenceIterator;
172
173    fn into_iter(self) -> Self::IntoIter {
174        OwnedSequenceIterator {
175            elements: VecDeque::from(self.elements),
176        }
177    }
178}
179
180impl FromIterator<Element> for Sequence {
181    fn from_iter<T: IntoIterator<Item = Element>>(iter: T) -> Self {
182        Vec::from_iter(iter).into()
183    }
184}
185
186impl IonEq for Sequence {
187    fn ion_eq(&self, other: &Self) -> bool {
188        self.elements.ion_eq(&other.elements)
189    }
190}
191
192impl IonDataOrd for Sequence {
193    fn ion_cmp(&self, other: &Self) -> Ordering {
194        self.elements.ion_cmp(&other.elements)
195    }
196}
197
198impl IonDataHash for Sequence {
199    fn ion_data_hash<H: Hasher>(&self, state: &mut H) {
200        self.elements.ion_data_hash(state)
201    }
202}
203
204#[derive(Clone)]
205pub struct OwnedSequenceIterator {
206    elements: VecDeque<Element>,
207}
208
209impl Iterator for OwnedSequenceIterator {
210    type Item = Element;
211
212    fn next(&mut self) -> Option<Self::Item> {
213        self.elements.pop_front()
214    }
215
216    fn size_hint(&self) -> (usize, Option<usize>) {
217        let len = self.elements.len();
218        (len, Some(len))
219    }
220}
221
222impl DoubleEndedIterator for OwnedSequenceIterator {
223    fn next_back(&mut self) -> Option<Self::Item> {
224        self.elements.pop_back()
225    }
226}
227
228impl Debug for OwnedSequenceIterator {
229    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
230        f.debug_tuple("OwnedSequenceIterator")
231            .field(&self.elements)
232            .finish()
233    }
234}
235
236#[cfg(test)]
237mod tests {
238    use crate::{ion_list, Element};
239
240    #[test]
241    fn owned_sequence() {
242        let list: Element = ion_list![true, false, "hello"].into();
243        let seq = list.try_into_sequence().unwrap();
244        let mut it = seq.into_iter();
245
246        assert_eq!(
247            format!("{it:?}"),
248            "OwnedSequenceIterator([true, false, \"hello\"])"
249        );
250
251        assert_eq!(it.size_hint(), (3, Some(3)));
252        assert_eq!(it.next(), Some(true.into()));
253        assert_eq!(it.size_hint(), (2, Some(2)));
254        assert_eq!(it.next(), Some(false.into()));
255        assert_eq!(it.size_hint(), (1, Some(1)));
256        assert_eq!(it.next(), Some("hello".into()));
257        assert_eq!(it.size_hint(), (0, Some(0)));
258        assert_eq!(it.next(), None);
259    }
260}