1use crate::element::builders::SequenceBuilder;
2use crate::element::iterators::SequenceIterator;
3use crate::ion_data::{IonDataHash, IonEq};
4use crate::text::text_formatter::FmtValueFormatter;
5use crate::{Element, Sequence};
6use delegate::delegate;
7use std::fmt::{Display, Formatter};
8use std::hash::Hasher;
9
10#[derive(Debug, Clone, PartialEq)]
26pub struct SExp(pub Sequence);
27
28impl SExp {
29 pub fn new(elements: impl Into<Sequence>) -> Self {
30 SExp(elements.into())
31 }
32}
33
34impl SExp {
35 delegate! {
36 to self.0 {
37 pub fn clone_builder(&self) -> SequenceBuilder;
38 pub fn elements(&self) -> SequenceIterator<'_>;
39 pub fn get(&self, index: usize) -> Option<&Element>;
40 pub fn len(&self) -> usize;
41 pub fn is_empty(&self) -> bool;
42 }
43 }
44}
45
46impl IonEq for SExp {
47 fn ion_eq(&self, other: &Self) -> bool {
48 self.0.ion_eq(&other.0)
50 }
51}
52
53impl IonDataHash for SExp {
54 fn ion_data_hash<H: Hasher>(&self, state: &mut H) {
55 self.0.ion_data_hash(state)
56 }
57}
58
59impl AsRef<Sequence> for SExp {
60 fn as_ref(&self) -> &Sequence {
61 &self.0
62 }
63}
64
65impl AsRef<[Element]> for SExp {
66 fn as_ref(&self) -> &[Element] {
67 self.0.as_ref()
68 }
69}
70
71impl<'a> IntoIterator for &'a SExp {
73 type Item = &'a Element;
74 type IntoIter = SequenceIterator<'a>;
75
76 fn into_iter(self) -> Self::IntoIter {
77 self.elements()
78 }
79}
80
81impl Display for SExp {
82 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
83 let mut ivf = FmtValueFormatter { output: f };
84 ivf.format_sexp(self).map_err(|_| std::fmt::Error)?;
85 Ok(())
86 }
87}
88
89impl From<Sequence> for SExp {
90 fn from(sequence: Sequence) -> Self {
91 SExp(sequence)
92 }
93}
94
95impl From<Vec<Element>> for SExp {
96 fn from(elements: Vec<Element>) -> Self {
97 Self(elements.into())
98 }
99}
100
101impl FromIterator<Element> for SExp {
102 fn from_iter<T: IntoIterator<Item = Element>>(iter: T) -> Self {
103 Vec::from_iter(iter).into()
104 }
105}
106
107impl From<SExp> for Sequence {
108 fn from(value: SExp) -> Self {
109 value.0
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use crate::{ion_sexp, Element, IonResult, SExp};
116
117 #[test]
118 fn for_element_in_sexp() -> IonResult<()> {
119 let sexp = ion_sexp!(1 2 3);
121 let mut sum = 0;
122 for element in &sexp {
123 sum += element.expect_int()?.expect_i64()?;
124 }
125 assert_eq!(sum, 6i64);
126 Ok(())
127 }
128
129 #[test]
130 fn sexp_from_vec() -> IonResult<()> {
131 let elements = vec![Element::int(1), Element::int(2), Element::int(3)];
132 let actual: SExp = elements.into();
133 let expected = ion_sexp!(1 2 3);
134 assert_eq!(actual, expected);
135 Ok(())
136 }
137
138 #[test]
139 fn sexp_from_iter() -> IonResult<()> {
140 let elements = vec![Element::int(1), Element::int(2), Element::int(3)];
141 let actual: SExp = elements.into_iter().collect();
142 let expected = ion_sexp!(1 2 3);
143 assert_eq!(actual, expected);
144 Ok(())
145 }
146}