use crate::{tags, Index, Result, Stream, Value};
impl<T: Value> Value for [T] {
fn stream<'a, S: Stream<'a> + ?Sized>(&'a self, stream: &mut S) -> Result {
stream.seq_begin(Some(self.len()))?;
for elem in self {
stream.seq_value_begin()?;
stream.value(elem)?;
stream.seq_value_end()?;
}
stream.seq_end()
}
}
impl<T: Value, const N: usize> Value for [T; N] {
fn stream<'a, S: Stream<'a> + ?Sized>(&'a self, stream: &mut S) -> Result {
stream.tagged_begin(Some(&tags::CONSTANT_SIZE), None, None)?;
stream.value(self as &'a [T])?;
stream.tagged_end(Some(&tags::CONSTANT_SIZE), None, None)
}
}
macro_rules! tuple {
($(
$len:expr => ( $(self.$i:tt: $ty:ident,)+ ),
)+) => {
$(
impl<$($ty: Value),+> Value for ($($ty,)+) {
fn stream<'sval, S: Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> Result {
stream.tuple_begin(None, None, None, Some($len))?;
$(
stream.tuple_value_begin(None, &Index::new($i).with_tag(&tags::VALUE_OFFSET))?;
stream.value(&self.$i)?;
stream.tuple_value_end(None, &Index::new($i).with_tag(&tags::VALUE_OFFSET))?;
)+
stream.tuple_end(None, None, None)
}
}
)+
}
}
tuple! {
1 => (
self.0: T0,
),
2 => (
self.0: T0,
self.1: T1,
),
3 => (
self.0: T0,
self.1: T1,
self.2: T2,
),
4 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
),
5 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
),
6 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
),
7 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
),
8 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
),
9 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
),
10 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
),
11 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
),
12 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
self.11: T11,
),
13 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
self.11: T11,
self.12: T12,
),
14 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
self.11: T11,
self.12: T12,
self.13: T13,
),
15 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
self.11: T11,
self.12: T12,
self.13: T13,
self.14: T14,
),
16 => (
self.0: T0,
self.1: T1,
self.2: T2,
self.3: T3,
self.4: T4,
self.5: T5,
self.6: T6,
self.7: T7,
self.8: T8,
self.9: T9,
self.10: T10,
self.11: T11,
self.12: T12,
self.13: T13,
self.14: T14,
self.15: T15,
),
}
#[cfg(feature = "alloc")]
mod alloc_support {
use super::*;
use crate::std::vec::Vec;
impl<T: Value> Value for Vec<T> {
fn stream<'a, S: Stream<'a> + ?Sized>(&'a self, stream: &mut S) -> Result {
(&**self).stream(stream)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn array_tag() {
assert_eq!(Some(tags::CONSTANT_SIZE), [true, false].tag());
}
}