Skip to main content

cbor_core/
array.rs

1use std::convert::Into;
2
3use crate::Value;
4
5/// Conversion helper for [`Value::array`].
6///
7/// This type wraps `Vec<Value>` and provides `From` implementations
8/// for common collection types, so that `Value::array()` can accept
9/// them all through a single `impl Into<Array>` bound.
10///
11/// Supported source types (where `T: Into<Value>`):
12///
13/// - `[T; N]` (fixed-size array)
14/// - `&[T]` (slice; requires `T: Copy`)
15/// - `Vec<T>` (vector)
16/// - `Box<[T]>` (boxed slice)
17/// - `()` (empty array)
18///
19/// Elements are converted to `Value` via their `Into<Value>`
20/// implementation. This means any type that implements
21/// `Into<Value>` (integers, strings, booleans, floats, nested
22/// `Value`s, etc.) can be used as elements.
23///
24/// ```
25/// # use cbor_core::Value;
26/// // From a fixed-size array of integers:
27/// let a = Value::array([1, 2, 3]);
28///
29/// // From a Vec of strings:
30/// let b = Value::array(vec!["x", "y"]);
31///
32/// // From a slice:
33/// let items: &[i32] = &[10, 20];
34/// let c = Value::array(items);
35///
36/// // Empty array via ():
37/// let d = Value::array(());
38/// assert_eq!(d.len(), Some(0));
39/// ```
40#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
41pub struct Array<'a>(pub(crate) Vec<Value<'a>>);
42
43impl<'a> Array<'a> {
44    /// Create an empty array.
45    #[must_use]
46    pub const fn new() -> Self {
47        Self(Vec::new())
48    }
49
50    /// Borrow the inner `Vec`.
51    #[must_use]
52    pub const fn get_ref(&self) -> &Vec<Value<'a>> {
53        &self.0
54    }
55
56    /// Mutably borrow the inner `Vec`.
57    pub const fn get_mut(&mut self) -> &mut Vec<Value<'a>> {
58        &mut self.0
59    }
60
61    /// Unwrap into the inner `Vec`.
62    #[must_use]
63    pub fn into_inner(self) -> Vec<Value<'a>> {
64        self.0
65    }
66
67    /// Build an array from an iterator of values.
68    ///
69    /// This is the write-side counterpart of iterating a CBOR sequence
70    /// into an array. For the fallible input produced by
71    /// [`SequenceDecoder`](crate::SequenceDecoder) and
72    /// [`SequenceReader`](crate::SequenceReader), use
73    /// [`try_from_sequence`](Self::try_from_sequence) instead.
74    ///
75    /// ```
76    /// # use cbor_core::{Array, Value};
77    /// let a = Array::from_sequence([Value::from(1), Value::from(2), Value::from(3)]);
78    /// assert_eq!(a.get_ref().len(), 3);
79    /// ```
80    pub fn from_sequence<I>(items: I) -> Self
81    where
82        I: IntoIterator<Item = Value<'a>>,
83    {
84        Self(items.into_iter().collect())
85    }
86
87    /// Build an array from a fallible iterator of values, stopping at
88    /// the first error.
89    ///
90    /// Accepts any `IntoIterator<Item = Result<Value, E>>`, which
91    /// includes both [`SequenceDecoder`](crate::SequenceDecoder)
92    /// (`E = Error`) and [`SequenceReader`](crate::SequenceReader)
93    /// (`E = IoError`).
94    ///
95    /// ```
96    /// # use cbor_core::{Array, DecodeOptions, Error};
97    /// // Three concatenated CBOR items: 0x01, 0x02, 0x03.
98    /// let a: Array = Array::try_from_sequence(
99    ///     DecodeOptions::new().sequence_decoder(&[0x01, 0x02, 0x03]),
100    /// ).unwrap();
101    /// assert_eq!(a.get_ref().len(), 3);
102    /// ```
103    pub fn try_from_sequence<I, E>(items: I) -> Result<Self, E>
104    where
105        I: IntoIterator<Item = Result<Value<'a>, E>>,
106    {
107        items.into_iter().collect::<Result<Vec<_>, _>>().map(Self)
108    }
109}
110
111impl<'a, T: Into<Value<'a>> + Copy> From<&[T]> for Array<'a> {
112    fn from(slice: &[T]) -> Self {
113        Self(slice.iter().map(|&x| x.into()).collect())
114    }
115}
116
117impl<'a, const N: usize, T: Into<Value<'a>>> From<[T; N]> for Array<'a> {
118    fn from(array: [T; N]) -> Self {
119        Self(array.into_iter().map(Into::into).collect())
120    }
121}
122
123impl<'a, T: Into<Value<'a>>> From<Vec<T>> for Array<'a> {
124    fn from(vec: Vec<T>) -> Self {
125        Self(vec.into_iter().map(Into::into).collect())
126    }
127}
128
129impl<'a, T: Into<Value<'a>>> From<Box<[T]>> for Array<'a> {
130    fn from(boxed: Box<[T]>) -> Self {
131        Self(Vec::from(boxed).into_iter().map(Into::into).collect())
132    }
133}
134
135impl From<()> for Array<'_> {
136    fn from((): ()) -> Self {
137        Self(Vec::new())
138    }
139}