Skip to main content

deser_core/foreign_impls/
arrayvec.rs

1//! `ArrayVec` and `ArrayString` of `arrayvec`.
2//!
3//! `ArrayVec` is serialized like `Vec`: `ArrayVec<u8, CAP>` as bytes,
4//! everything else as sequence.  `ArrayString` is serialized like `String`.
5//! Deserializing more elements or a longer string than the capacity is an
6//! error.
7use alloc::borrow::Cow;
8use alloc::format;
9use alloc::vec::Vec;
10
11use ::arrayvec::{ArrayString, ArrayVec};
12
13use crate::State;
14use crate::Text;
15use crate::adapters::bytes::{BytesBufImpl, encoding_adapter};
16use crate::adapters::ser_impls::serialize_as_slice;
17use crate::adapters::{DeserializeAs, Same, SerializeAs};
18use crate::de::impls::{SeqTarget, collection_methods, collection_methods_as, seq_sink};
19use crate::de::update::Collection;
20use crate::de::{Deserialize, Sink, SinkHandle};
21use crate::error::{Error, ErrorKind};
22use crate::event::Atom;
23use crate::ser::impls::serialize_slice;
24use crate::ser::{Chunk, Serialize, plain_atom};
25
26make_slot_wrapper!(SlotWrapper);
27
28serialize_slice!(
29    [T: Serialize, const CAP: usize] ArrayVec<T, CAP>,
30);
31
32serialize_as_slice! {
33    [T: Sync, A: SerializeAs<T>, const CAP: usize] ArrayVec<T, CAP> => ArrayVec<A, CAP>;
34}
35
36/// Creates the error for values that exceed the capacity.
37#[cold]
38fn capacity_exceeded(what: &str, capacity: usize) -> Error {
39    Error::new(
40        ErrorKind::WrongLength,
41        format!("{what} exceeds the capacity of {capacity}"),
42    )
43}
44
45/// Converts a vector into an `ArrayVec`.
46fn array_vec_from_vec<T, const CAP: usize>(vec: Vec<T>) -> Result<ArrayVec<T, CAP>, Error> {
47    if vec.len() > CAP {
48        return Err(capacity_exceeded("ArrayVec", CAP));
49    }
50    let mut rv = ArrayVec::new();
51    rv.extend(vec);
52    Ok(rv)
53}
54
55impl<T: Send, const CAP: usize> SeqTarget<T> for ArrayVec<T, CAP> {
56    const NAME: &'static str = "ArrayVec";
57
58    #[inline]
59    fn from_vec(vec: Vec<T>) -> Result<Self, Error> {
60        array_vec_from_vec(vec)
61    }
62}
63
64impl<'de, T: Deserialize<'de>, const CAP: usize> Deserialize<'de> for ArrayVec<T, CAP> {
65    #[inline]
66    fn deserialize_into<'out>(
67        out: &'out mut Option<Self>,
68        state: &mut State,
69    ) -> SinkHandle<'out, 'de> {
70        seq_sink::<Self, T, Same>(out, state)
71    }
72
73    collection_methods!(Same);
74}
75
76impl<'de, T: Send, A: DeserializeAs<'de, T>, const CAP: usize> DeserializeAs<'de, ArrayVec<T, CAP>>
77    for ArrayVec<A, CAP>
78{
79    fn deserialize_into_as<'out>(
80        out: &'out mut Option<ArrayVec<T, CAP>>,
81        state: &mut State,
82    ) -> SinkHandle<'out, 'de> {
83        seq_sink::<ArrayVec<T, CAP>, T, A>(out, state)
84    }
85
86    collection_methods_as!(ArrayVec<T, CAP>);
87}
88
89impl<T: Send, const CAP: usize> Collection<T> for ArrayVec<T, CAP> {
90    fn empty() -> Self {
91        ArrayVec::new()
92    }
93
94    fn add(&mut self, value: T) -> Result<(), Error> {
95        self.try_push(value)
96            .map_err(|_| capacity_exceeded("ArrayVec", CAP))
97    }
98}
99
100impl<const CAP: usize> BytesBufImpl for ArrayVec<u8, CAP> {
101    #[inline]
102    fn bytes(&self) -> &[u8] {
103        self
104    }
105
106    #[inline]
107    fn from_vec(bytes: Vec<u8>) -> Result<Self, Error> {
108        array_vec_from_vec(bytes)
109    }
110
111    #[inline]
112    fn deserialize_into<'a, 'de>(
113        out: &'a mut Option<Self>,
114        state: &mut State,
115    ) -> SinkHandle<'a, 'de> {
116        Deserialize::deserialize_into(out, state)
117    }
118}
119
120encoding_adapter!(
121    [const CAP: usize,] ArrayVec<u8, CAP>,
122);
123
124impl<const CAP: usize> Serialize for ArrayString<CAP> {
125    begin_without_finish!();
126    plain_atom!(|v| Atom::Str(Text::borrowed(v.as_str())));
127
128    fn serialize(&self, _state: &mut State) -> Result<Chunk<'_>, Error> {
129        Ok(Chunk::Atom(Atom::Str(Text::borrowed(self.as_str()))))
130    }
131}
132
133impl<'de, const CAP: usize> Sink<'de> for SlotWrapper<ArrayString<CAP>> {
134    fn expecting(&self) -> Cow<'_, str> {
135        Cow::Borrowed("string")
136    }
137
138    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
139        let mut rv = ArrayString::new();
140        match atom {
141            Atom::Str(ref value) | Atom::Lexical(ref value) => rv
142                .try_push_str(value)
143                .map_err(|_| capacity_exceeded("string", CAP))?,
144            Atom::Char(value) => rv
145                .try_push(value)
146                .map_err(|_| capacity_exceeded("string", CAP))?,
147            other => return self.unexpected_atom(other, state),
148        }
149        **self = Some(rv);
150        Ok(())
151    }
152}
153
154impl<'de, const CAP: usize> Deserialize<'de> for ArrayString<CAP> {
155    fn deserialize_into<'out>(
156        out: &'out mut Option<Self>,
157        _state: &mut State,
158    ) -> SinkHandle<'out, 'de> {
159        SlotWrapper::make_handle(out)
160    }
161
162    #[inline]
163    fn __private_atom_into(
164        out: &mut Option<Self>,
165        atom: Atom,
166        state: &mut State,
167    ) -> Result<(), Error> {
168        let sink = SlotWrapper::wrap(out);
169        sink.atom(atom, state)?;
170        sink.finish(state)
171    }
172
173    #[inline]
174    fn __private_borrowed_atom_into(
175        out: &mut Option<Self>,
176        atom: Atom<'de>,
177        state: &mut State,
178    ) -> Result<(), Error> {
179        // the sink does not borrow
180        Self::__private_atom_into(out, atom, state)
181    }
182}