1use sval::{tags, Index, Result, Stream};
2
3use crate::ValueRef;
4
5impl<'sval, T: ValueRef<'sval>> ValueRef<'sval> for [T] {
6 fn stream_ref<S: Stream<'sval> + ?Sized>(&self, stream: &mut S) -> Result {
7 stream.seq_begin(Some(self.len()))?;
8
9 for elem in self {
10 stream.seq_value_begin()?;
11 crate::stream_ref(stream, elem)?;
12 stream.seq_value_end()?;
13 }
14
15 stream.seq_end()
16 }
17}
18
19impl<'sval, T: ValueRef<'sval>, const N: usize> ValueRef<'sval> for [T; N] {
20 fn stream_ref<S: Stream<'sval> + ?Sized>(&self, stream: &mut S) -> Result {
21 stream.tagged_begin(Some(&tags::CONSTANT_SIZE), None, None)?;
22 stream.seq_begin(Some(self.len()))?;
23
24 for elem in self {
25 stream.seq_value_begin()?;
26 crate::stream_ref(stream, elem)?;
27 stream.seq_value_end()?;
28 }
29
30 stream.seq_end()?;
31 stream.tagged_end(Some(&tags::CONSTANT_SIZE), None, None)
32 }
33}
34
35macro_rules! tuple {
36 ($(
37 $len:expr => ( $(self.$i:tt: $ty:ident,)+ ),
38 )+) => {
39 $(
40 impl<'sval, $($ty: ValueRef<'sval>),+> ValueRef<'sval> for ($($ty,)+) {
41 fn stream_ref<S: Stream<'sval> + ?Sized>(&self, stream: &mut S) -> Result {
42 stream.tuple_begin(None, None, None, Some($len))?;
43
44 $(
45 stream.tuple_value_begin(None, &Index::new($i).with_tag(&sval::tags::VALUE_OFFSET))?;
46 crate::stream_ref(stream, &self.$i)?;
47 stream.tuple_value_end(None, &Index::new($i).with_tag(&sval::tags::VALUE_OFFSET))?;
48 )+
49
50 stream.tuple_end(None, None, None)
51 }
52 }
53 )+
54 }
55}
56
57tuple! {
58 1 => (
59 self.0: T0,
60 ),
61 2 => (
62 self.0: T0,
63 self.1: T1,
64 ),
65 3 => (
66 self.0: T0,
67 self.1: T1,
68 self.2: T2,
69 ),
70 4 => (
71 self.0: T0,
72 self.1: T1,
73 self.2: T2,
74 self.3: T3,
75 ),
76 5 => (
77 self.0: T0,
78 self.1: T1,
79 self.2: T2,
80 self.3: T3,
81 self.4: T4,
82 ),
83 6 => (
84 self.0: T0,
85 self.1: T1,
86 self.2: T2,
87 self.3: T3,
88 self.4: T4,
89 self.5: T5,
90 ),
91 7 => (
92 self.0: T0,
93 self.1: T1,
94 self.2: T2,
95 self.3: T3,
96 self.4: T4,
97 self.5: T5,
98 self.6: T6,
99 ),
100 8 => (
101 self.0: T0,
102 self.1: T1,
103 self.2: T2,
104 self.3: T3,
105 self.4: T4,
106 self.5: T5,
107 self.6: T6,
108 self.7: T7,
109 ),
110 9 => (
111 self.0: T0,
112 self.1: T1,
113 self.2: T2,
114 self.3: T3,
115 self.4: T4,
116 self.5: T5,
117 self.6: T6,
118 self.7: T7,
119 self.8: T8,
120 ),
121 10 => (
122 self.0: T0,
123 self.1: T1,
124 self.2: T2,
125 self.3: T3,
126 self.4: T4,
127 self.5: T5,
128 self.6: T6,
129 self.7: T7,
130 self.8: T8,
131 self.9: T9,
132 ),
133 11 => (
134 self.0: T0,
135 self.1: T1,
136 self.2: T2,
137 self.3: T3,
138 self.4: T4,
139 self.5: T5,
140 self.6: T6,
141 self.7: T7,
142 self.8: T8,
143 self.9: T9,
144 self.10: T10,
145 ),
146 12 => (
147 self.0: T0,
148 self.1: T1,
149 self.2: T2,
150 self.3: T3,
151 self.4: T4,
152 self.5: T5,
153 self.6: T6,
154 self.7: T7,
155 self.8: T8,
156 self.9: T9,
157 self.10: T10,
158 self.11: T11,
159 ),
160 13 => (
161 self.0: T0,
162 self.1: T1,
163 self.2: T2,
164 self.3: T3,
165 self.4: T4,
166 self.5: T5,
167 self.6: T6,
168 self.7: T7,
169 self.8: T8,
170 self.9: T9,
171 self.10: T10,
172 self.11: T11,
173 self.12: T12,
174 ),
175 14 => (
176 self.0: T0,
177 self.1: T1,
178 self.2: T2,
179 self.3: T3,
180 self.4: T4,
181 self.5: T5,
182 self.6: T6,
183 self.7: T7,
184 self.8: T8,
185 self.9: T9,
186 self.10: T10,
187 self.11: T11,
188 self.12: T12,
189 self.13: T13,
190 ),
191 15 => (
192 self.0: T0,
193 self.1: T1,
194 self.2: T2,
195 self.3: T3,
196 self.4: T4,
197 self.5: T5,
198 self.6: T6,
199 self.7: T7,
200 self.8: T8,
201 self.9: T9,
202 self.10: T10,
203 self.11: T11,
204 self.12: T12,
205 self.13: T13,
206 self.14: T14,
207 ),
208 16 => (
209 self.0: T0,
210 self.1: T1,
211 self.2: T2,
212 self.3: T3,
213 self.4: T4,
214 self.5: T5,
215 self.6: T6,
216 self.7: T7,
217 self.8: T8,
218 self.9: T9,
219 self.10: T10,
220 self.11: T11,
221 self.12: T12,
222 self.13: T13,
223 self.14: T14,
224 self.15: T15,
225 ),
226}
227
228#[cfg(feature = "alloc")]
229mod alloc_support {
230 use super::*;
231
232 use crate::std::vec::Vec;
233
234 impl<'sval, T: ValueRef<'sval>> ValueRef<'sval> for Vec<T> {
235 fn stream_ref<S: Stream<'sval> + ?Sized>(&self, stream: &mut S) -> Result {
236 (&**self).stream_ref(stream)
237 }
238 }
239}
240
241#[cfg(test)]
242mod tests {
243 use crate::test::{compat_case, Ref, Token};
244
245 #[test]
246 fn seq_compat() {
247 compat_case(
248 &[Ref(&1)] as &[Ref<&i32>],
249 &[
250 Token::SeqBegin(Some(1)),
251 Token::SeqValueBegin,
252 Token::I32(1),
253 Token::SeqValueEnd,
254 Token::SeqEnd,
255 ],
256 );
257
258 compat_case(
259 &[Ref(&1)],
260 &[
261 Token::TaggedBegin(Some(sval::tags::CONSTANT_SIZE), None, None),
262 Token::SeqBegin(Some(1)),
263 Token::SeqValueBegin,
264 Token::I32(1),
265 Token::SeqValueEnd,
266 Token::SeqEnd,
267 Token::TaggedEnd(Some(sval::tags::CONSTANT_SIZE), None, None),
268 ],
269 );
270
271 compat_case(
272 &(Ref(&1), Ref(&2), Ref(&3)),
273 &[
274 Token::TupleBegin(None, None, None, Some(3)),
275 Token::TupleValueBegin(None, sval::Index::new(0)),
276 Token::I32(1),
277 Token::TupleValueEnd(None, sval::Index::new(0)),
278 Token::TupleValueBegin(None, sval::Index::new(1)),
279 Token::I32(2),
280 Token::TupleValueEnd(None, sval::Index::new(1)),
281 Token::TupleValueBegin(None, sval::Index::new(2)),
282 Token::I32(3),
283 Token::TupleValueEnd(None, sval::Index::new(2)),
284 Token::TupleEnd(None, None, None),
285 ],
286 );
287
288 #[cfg(feature = "std")]
289 {
290 compat_case(
291 &vec![Ref(&1)],
292 &[
293 Token::SeqBegin(Some(1)),
294 Token::SeqValueBegin,
295 Token::I32(1),
296 Token::SeqValueEnd,
297 Token::SeqEnd,
298 ],
299 );
300 }
301 }
302}