1use crate::{
2 flattener::{Flatten, Flattener},
3 label::Empty,
4};
5use sval::{Index, Label, Stream, Tag};
6
7pub fn flatten_to_tuple<'sval>(
14 stream: &mut (impl Stream<'sval> + ?Sized),
15 value: &'sval (impl sval::Value + ?Sized),
16 offset: isize,
17) -> sval::Result<isize> {
18 let mut stream = FlattenToTuple::new(stream, offset);
19
20 value.stream(&mut stream)?;
21
22 Ok(stream.end().0)
23}
24
25pub struct FlattenToTuple<'sval, S> {
29 inner: Flattener<'sval, TupleFlatten<S>>,
30}
31
32impl<'sval, S: sval::Stream<'sval>> FlattenToTuple<'sval, S> {
33 pub fn new(stream: S, offset: isize) -> Self {
40 FlattenToTuple {
41 inner: Flattener::begin(
42 TupleFlatten {
43 stream,
44 label_stream: Empty,
45 },
46 offset,
47 ),
48 }
49 }
50
51 pub fn end(self) -> (isize, S) {
57 let (offset, TupleFlatten { stream, .. }) = self.inner.end();
58
59 (offset, stream)
60 }
61}
62
63impl_stream_forward!({ impl<'sval, S: Stream<'sval>> Stream<'sval> for FlattenToTuple<'sval, S> } => x => { x.inner });
64
65struct TupleFlatten<S> {
66 stream: S,
67 label_stream: Empty,
68}
69
70impl<'sval, S: Stream<'sval>> Flatten<'sval> for TupleFlatten<S> {
71 type Stream = S;
72 type LabelStream = Empty;
73
74 fn stream(&mut self) -> &mut Self::Stream {
75 &mut self.stream
76 }
77
78 fn label_stream(&mut self) -> &mut Self::LabelStream {
79 &mut self.label_stream
80 }
81
82 fn flattened_value_begin(
83 &mut self,
84 tag: Option<&Tag>,
85 _: &Label,
86 index: &Index,
87 ) -> sval::Result {
88 self.stream.tuple_value_begin(tag, index)
89 }
90
91 fn flattened_value_end(&mut self, tag: Option<&Tag>, _: &Label, index: &Index) -> sval::Result {
92 self.stream.tuple_value_end(tag, index)
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use sval_derive_macros::*;
99
100 use super::*;
101
102 struct Outer<I>(i32, I, i32);
103
104 impl<I: sval::Value> sval::Value for Outer<I> {
105 fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result {
106 let mut offset = 0;
107
108 stream.tuple_begin(None, Some(&Label::new("Outer")), None, None)?;
109
110 stream.tuple_value_begin(
111 None,
112 &Index::from(offset).with_tag(&sval::tags::VALUE_OFFSET),
113 )?;
114 stream.i32(self.0)?;
115 stream.tuple_value_end(
116 None,
117 &Index::from(offset).with_tag(&sval::tags::VALUE_OFFSET),
118 )?;
119 offset += 1;
120
121 offset = flatten_to_tuple(&mut *stream, &self.1, offset)?;
122
123 stream.tuple_value_begin(
124 None,
125 &Index::from(offset).with_tag(&sval::tags::VALUE_OFFSET),
126 )?;
127 stream.i32(self.2)?;
128 stream.tuple_value_end(
129 None,
130 &Index::from(offset).with_tag(&sval::tags::VALUE_OFFSET),
131 )?;
132 offset += 1;
133
134 let _ = offset;
135 stream.tuple_end(None, Some(&Label::new("Outer")), None)
136 }
137 }
138
139 #[test]
140 fn flatten_record() {
141 #[derive(Value)]
142 #[sval(unindexed_fields)]
143 struct Inner {
144 b: i32,
145 c: i32,
146 }
147
148 sval_test::assert_tokens(&Outer(1, Inner { b: 2, c: 3 }, 4), {
149 use sval_test::Token::*;
150
151 &[
152 TupleBegin(None, Some(Label::new("Outer")), None, None),
153 TupleValueBegin(None, Index::new(0)),
154 I32(1),
155 TupleValueEnd(None, Index::new(0)),
156 TupleValueBegin(None, Index::new(1)),
157 I32(2),
158 TupleValueEnd(None, Index::new(1)),
159 TupleValueBegin(None, Index::new(2)),
160 I32(3),
161 TupleValueEnd(None, Index::new(2)),
162 TupleValueBegin(None, Index::new(3)),
163 I32(4),
164 TupleValueEnd(None, Index::new(3)),
165 TupleEnd(None, Some(Label::new("Outer")), None),
166 ]
167 });
168 }
169
170 #[test]
171 fn flatten_tuple() {
172 sval_test::assert_tokens(&Outer(1, (2, 3), 4), {
173 use sval_test::Token::*;
174
175 &[
176 TupleBegin(None, Some(Label::new("Outer")), None, None),
177 TupleValueBegin(None, Index::new(0)),
178 I32(1),
179 TupleValueEnd(None, Index::new(0)),
180 TupleValueBegin(None, Index::new(1)),
181 I32(2),
182 TupleValueEnd(None, Index::new(1)),
183 TupleValueBegin(None, Index::new(2)),
184 I32(3),
185 TupleValueEnd(None, Index::new(2)),
186 TupleValueBegin(None, Index::new(3)),
187 I32(4),
188 TupleValueEnd(None, Index::new(3)),
189 TupleEnd(None, Some(Label::new("Outer")), None),
190 ]
191 });
192 }
193
194 #[test]
195 fn flatten_seq() {
196 sval_test::assert_tokens(&Outer(1, [2, 3], 4), {
197 use sval_test::Token::*;
198
199 &[
200 TupleBegin(None, Some(Label::new("Outer")), None, None),
201 TupleValueBegin(None, Index::new(0)),
202 I32(1),
203 TupleValueEnd(None, Index::new(0)),
204 TupleValueBegin(None, Index::new(1)),
205 I32(2),
206 TupleValueEnd(None, Index::new(1)),
207 TupleValueBegin(None, Index::new(2)),
208 I32(3),
209 TupleValueEnd(None, Index::new(2)),
210 TupleValueBegin(None, Index::new(3)),
211 I32(4),
212 TupleValueEnd(None, Index::new(3)),
213 TupleEnd(None, Some(Label::new("Outer")), None),
214 ]
215 });
216 }
217
218 #[test]
219 fn flatten_map() {
220 sval_test::assert_tokens(
221 &Outer(
222 1,
223 sval::MapSlice::new(&[(["b1", "b2"], 2), (["c1", "c2"], 3)]),
224 4,
225 ),
226 {
227 use sval_test::Token::*;
228
229 &[
230 TupleBegin(None, Some(Label::new("Outer")), None, None),
231 TupleValueBegin(None, Index::new(0)),
232 I32(1),
233 TupleValueEnd(None, Index::new(0)),
234 TupleValueBegin(None, Index::new(1)),
235 I32(2),
236 TupleValueEnd(None, Index::new(1)),
237 TupleValueBegin(None, Index::new(2)),
238 I32(3),
239 TupleValueEnd(None, Index::new(2)),
240 TupleValueBegin(None, Index::new(3)),
241 I32(4),
242 TupleValueEnd(None, Index::new(3)),
243 TupleEnd(None, Some(Label::new("Outer")), None),
244 ]
245 },
246 );
247 }
248
249 #[test]
250 fn flatten_record_tuple() {
251 #[derive(Value)]
252 struct Inner {
253 b: i32,
254 c: i32,
255 }
256
257 sval_test::assert_tokens(&Outer(1, Inner { b: 2, c: 3 }, 4), {
258 use sval_test::Token::*;
259
260 &[
261 TupleBegin(None, Some(Label::new("Outer")), None, None),
262 TupleValueBegin(None, Index::new(0)),
263 I32(1),
264 TupleValueEnd(None, Index::new(0)),
265 TupleValueBegin(None, Index::new(1)),
266 I32(2),
267 TupleValueEnd(None, Index::new(1)),
268 TupleValueBegin(None, Index::new(2)),
269 I32(3),
270 TupleValueEnd(None, Index::new(2)),
271 TupleValueBegin(None, Index::new(3)),
272 I32(4),
273 TupleValueEnd(None, Index::new(3)),
274 TupleEnd(None, Some(Label::new("Outer")), None),
275 ]
276 });
277 }
278
279 #[test]
280 fn flatten_enum() {
281 #[derive(Value)]
282 enum Inner {
283 #[sval(label = "b")]
284 A(i32),
285 B {
286 b: i32,
287 c: i32,
288 },
289 C(i32, i32),
290 }
291
292 sval_test::assert_tokens(&Outer(1, Inner::A(2), 4), {
293 use sval_test::Token::*;
294
295 &[
296 TupleBegin(None, Some(Label::new("Outer")), None, None),
297 TupleValueBegin(None, Index::new(0)),
298 I32(1),
299 TupleValueEnd(None, Index::new(0)),
300 TupleValueBegin(None, Index::new(1)),
301 I32(2),
302 TupleValueEnd(None, Index::new(1)),
303 TupleValueBegin(None, Index::new(2)),
304 I32(4),
305 TupleValueEnd(None, Index::new(2)),
306 TupleEnd(None, Some(Label::new("Outer")), None),
307 ]
308 });
309
310 sval_test::assert_tokens(&Outer(1, Inner::B { b: 2, c: 3 }, 4), {
311 use sval_test::Token::*;
312
313 &[
314 TupleBegin(None, Some(Label::new("Outer")), None, None),
315 TupleValueBegin(None, Index::new(0)),
316 I32(1),
317 TupleValueEnd(None, Index::new(0)),
318 TupleValueBegin(None, Index::new(1)),
319 I32(2),
320 TupleValueEnd(None, Index::new(1)),
321 TupleValueBegin(None, Index::new(2)),
322 I32(3),
323 TupleValueEnd(None, Index::new(2)),
324 TupleValueBegin(None, Index::new(3)),
325 I32(4),
326 TupleValueEnd(None, Index::new(3)),
327 TupleEnd(None, Some(Label::new("Outer")), None),
328 ]
329 });
330
331 sval_test::assert_tokens(&Outer(1, Inner::C(2, 3), 4), {
332 use sval_test::Token::*;
333
334 &[
335 TupleBegin(None, Some(Label::new("Outer")), None, None),
336 TupleValueBegin(None, Index::new(0)),
337 I32(1),
338 TupleValueEnd(None, Index::new(0)),
339 TupleValueBegin(None, Index::new(1)),
340 I32(2),
341 TupleValueEnd(None, Index::new(1)),
342 TupleValueBegin(None, Index::new(2)),
343 I32(3),
344 TupleValueEnd(None, Index::new(2)),
345 TupleValueBegin(None, Index::new(3)),
346 I32(4),
347 TupleValueEnd(None, Index::new(3)),
348 TupleEnd(None, Some(Label::new("Outer")), None),
349 ]
350 });
351 }
352}