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 /// # Errors
96 ///
97 /// Returns the first `Err` yielded by the iterator.
98 ///
99 /// ```
100 /// # use cbor_core::{Array, DecodeOptions, Error};
101 /// // Three concatenated CBOR items: 0x01, 0x02, 0x03.
102 /// let a: Array = Array::try_from_sequence(
103 /// DecodeOptions::new().sequence_decoder(&[0x01, 0x02, 0x03]),
104 /// ).unwrap();
105 /// assert_eq!(a.get_ref().len(), 3);
106 /// ```
107 pub fn try_from_sequence<I, E>(items: I) -> Result<Self, E>
108 where
109 I: IntoIterator<Item = Result<Value<'a>, E>>,
110 {
111 items.into_iter().collect::<Result<Vec<_>, _>>().map(Self)
112 }
113}
114
115impl<'a, T: Into<Value<'a>> + Copy> From<&[T]> for Array<'a> {
116 fn from(slice: &[T]) -> Self {
117 Self(slice.iter().map(|&x| x.into()).collect())
118 }
119}
120
121impl<'a, const N: usize, T: Into<Value<'a>>> From<[T; N]> for Array<'a> {
122 fn from(array: [T; N]) -> Self {
123 Self(array.into_iter().map(Into::into).collect())
124 }
125}
126
127impl<'a, T: Into<Value<'a>>> From<Vec<T>> for Array<'a> {
128 fn from(vec: Vec<T>) -> Self {
129 Self(vec.into_iter().map(Into::into).collect())
130 }
131}
132
133impl<'a, T: Into<Value<'a>>> From<Box<[T]>> for Array<'a> {
134 fn from(boxed: Box<[T]>) -> Self {
135 Self(Vec::from(boxed).into_iter().map(Into::into).collect())
136 }
137}
138
139impl From<()> for Array<'_> {
140 fn from((): ()) -> Self {
141 Self(Vec::new())
142 }
143}