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