1use alloc::boxed::Box;
16
17use crate::error::Error;
18use crate::rxml_util::Item;
19use crate::AsXml;
20
21use core::fmt;
22
23use bytes::BytesMut;
24
25pub struct OptionAsXml<T: Iterator>(Option<T>);
27
28impl<T: Iterator> OptionAsXml<T> {
29 pub fn new(inner: Option<T>) -> Self {
35 Self(inner)
36 }
37}
38
39impl<'x, T: Iterator<Item = Result<Item<'x>, Error>>> Iterator for OptionAsXml<T> {
40 type Item = Result<Item<'x>, Error>;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 self.0.as_mut()?.next()
44 }
45}
46
47impl<T: AsXml> AsXml for Option<T> {
50 type ItemIter<'x>
51 = OptionAsXml<T::ItemIter<'x>>
52 where
53 T: 'x;
54
55 fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
56 match self {
57 Some(ref value) => Ok(OptionAsXml(Some(T::as_xml_iter(value)?))),
58 None => Ok(OptionAsXml(None)),
59 }
60 }
61}
62
63pub struct BoxAsXml<T: Iterator>(Box<T>);
65
66impl<'x, T: Iterator<Item = Result<Item<'x>, Error>>> Iterator for BoxAsXml<T> {
67 type Item = Result<Item<'x>, Error>;
68
69 fn next(&mut self) -> Option<Self::Item> {
70 self.0.next()
71 }
72}
73
74impl<T: AsXml> AsXml for Box<T> {
76 type ItemIter<'x>
77 = BoxAsXml<T::ItemIter<'x>>
78 where
79 T: 'x;
80
81 fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
82 Ok(BoxAsXml(Box::new(T::as_xml_iter(self)?)))
83 }
84}
85
86impl<T: AsXml, E> AsXml for Result<T, E>
88where
89 for<'a> Error: From<&'a E>,
90{
91 type ItemIter<'x>
92 = T::ItemIter<'x>
93 where
94 Self: 'x;
95
96 fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
97 match self {
98 Self::Ok(v) => Ok(v.as_xml_iter()?),
99 Self::Err(e) => Err(e.into()),
100 }
101 }
102}
103
104pub struct PrintRawXml<'x, T>(pub &'x T);
106
107impl<'x, T: AsXml> fmt::Display for PrintRawXml<'x, T> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 let iter = match self.0.as_xml_iter() {
110 Ok(iter) => iter,
111 Err(err) => return write!(f, "<failed to serialize PrintRawXml: {:?}>", err),
112 };
113 let mut writer = rxml::writer::Encoder::new();
114 let mut buf = BytesMut::new();
115 for item in iter {
116 let item = match item {
117 Ok(item) => item,
118 Err(err) => return write!(f, "<failed to serialize PrintRawXml: {:?}>", err),
119 };
120 if let Err(err) = writer.encode(item.as_rxml_item(), &mut buf) {
121 return write!(f, "<failed to serialize PrintRawXml: {:?}>", err);
122 }
123 }
124 write!(f, "{}", std::str::from_utf8(&buf).unwrap())
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 use alloc::{borrow::Cow, vec};
135
136 #[test]
137 fn option_as_xml_terminates_immediately_for_none() {
138 let mut iter = OptionAsXml::<core::iter::Empty<_>>(None);
139 match iter.next() {
140 None => (),
141 other => panic!("unexpected item: {:?}", other),
142 }
143 }
144
145 #[test]
146 fn option_as_xml_passes_values_from_inner_some() {
147 let inner = vec![
148 Ok(Item::Text(Cow::Borrowed("hello world"))),
149 Ok(Item::ElementFoot),
150 ];
151 let mut iter = OptionAsXml(Some(inner.into_iter()));
152 match iter.next() {
153 Some(Ok(Item::Text(text))) => {
154 assert_eq!(text, "hello world");
155 }
156 other => panic!("unexpected item: {:?}", other),
157 }
158 match iter.next() {
159 Some(Ok(Item::ElementFoot)) => (),
160 other => panic!("unexpected item: {:?}", other),
161 }
162 match iter.next() {
163 None => (),
164 other => panic!("unexpected item: {:?}", other),
165 }
166 }
167
168 #[test]
169 fn box_as_xml_passes_values_from_inner() {
170 let inner = vec![
171 Ok(Item::Text(Cow::Borrowed("hello world"))),
172 Ok(Item::ElementFoot),
173 ];
174 let mut iter = BoxAsXml(Box::new(inner.into_iter()));
175 match iter.next() {
176 Some(Ok(Item::Text(text))) => {
177 assert_eq!(text, "hello world");
178 }
179 other => panic!("unexpected item: {:?}", other),
180 }
181 match iter.next() {
182 Some(Ok(Item::ElementFoot)) => (),
183 other => panic!("unexpected item: {:?}", other),
184 }
185 match iter.next() {
186 None => (),
187 other => panic!("unexpected item: {:?}", other),
188 }
189 }
190}