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}