deser_core/foreign_impls/
bstr.rs1use alloc::borrow::Cow;
13use alloc::boxed::Box;
14use alloc::string::ToString;
15use alloc::vec::Vec;
16use core::mem::take;
17
18use ::bstr::{BStr, BString};
19
20use crate::BytesFormat;
21use crate::State;
22use crate::Text;
23use crate::adapters::bytes::{BytesBufImpl, encoding_adapter};
24use crate::de::impls::{Via, deserialize_via};
25use crate::de::{Deserialize, Sink, SinkHandle};
26use crate::error::{Error, ErrorKind};
27use crate::event::{Atom, Bytes};
28use crate::ser::{Chunk, Serialize, plain_atom};
29
30make_slot_wrapper!(SlotWrapper);
31
32#[inline]
34fn bstr_atom(bytes: &[u8]) -> Atom<'_> {
35 match core::str::from_utf8(bytes) {
36 Ok(value) => Atom::Str(Text::borrowed(value)),
37 Err(_) => Atom::Bytes(Bytes::borrowed(bytes).with_fallback(const { &BytesFormat::SEQ })),
38 }
39}
40
41impl Serialize for BStr {
42 begin_without_finish!();
43
44 fn serialize(&self, _state: &mut State) -> Result<Chunk<'_>, Error> {
45 Ok(Chunk::Atom(bstr_atom(self)))
46 }
47}
48
49impl Serialize for BString {
50 begin_without_finish!();
51 plain_atom!(|v| bstr_atom(v));
52
53 fn serialize(&self, _state: &mut State) -> Result<Chunk<'_>, Error> {
54 Ok(Chunk::Atom(bstr_atom(self)))
55 }
56}
57
58#[inline]
62fn bstring_from_atom(atom: Atom) -> Result<BString, Atom> {
63 match atom {
64 Atom::Str(value) | Atom::Lexical(value) => Ok(BString::from(value.into_owned())),
65 Atom::Char(value) => Ok(BString::from(value.to_string())),
66 Atom::Bytes(value) => Ok(BString::from(value.into_owned())),
67 other => Err(other),
68 }
69}
70
71struct BStringSink<'a> {
73 out: &'a mut Option<BString>,
74 bytes: Vec<u8>,
75 element: Option<u8>,
76 is_seq: bool,
77}
78
79impl BStringSink<'_> {
80 #[inline]
81 fn flush(&mut self) {
82 if let Some(byte) = self.element.take() {
83 self.bytes.push(byte);
84 }
85 }
86}
87
88impl<'de> Sink<'de> for BStringSink<'_> {
89 fn expecting(&self) -> Cow<'_, str> {
90 Cow::Borrowed("byte string")
91 }
92
93 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
94 match bstring_from_atom(atom) {
95 Ok(value) => {
96 *self.out = Some(value);
97 Ok(())
98 }
99 Err(other) => self.unexpected_atom(other, state),
100 }
101 }
102
103 fn seq(&mut self, _state: &mut State) -> Result<(), Error> {
104 self.is_seq = true;
105 Ok(())
106 }
107
108 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
109 self.flush();
110 Ok(u8::deserialize_into(&mut self.element, state))
111 }
112
113 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
114 self.flush();
115 u8::__private_atom_into(&mut self.element, atom, state)
116 }
117
118 fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
119 if self.is_seq {
120 self.flush();
121 *self.out = Some(BString::from(take(&mut self.bytes)));
122 }
123 Ok(())
124 }
125}
126
127impl<'de> Deserialize<'de> for BString {
128 fn deserialize_into<'out>(
129 out: &'out mut Option<Self>,
130 state: &mut State,
131 ) -> SinkHandle<'out, 'de> {
132 SinkHandle::arena(
133 BStringSink {
134 out,
135 bytes: Vec::new(),
136 element: None,
137 is_seq: false,
138 },
139 state,
140 )
141 }
142
143 #[inline]
144 fn __private_atom_into(
145 out: &mut Option<Self>,
146 atom: Atom,
147 state: &mut State,
148 ) -> Result<(), Error> {
149 match bstring_from_atom(atom) {
150 Ok(value) => {
151 *out = Some(value);
152 Ok(())
153 }
154 Err(other) => {
155 let mut sink = BStringSink {
156 out,
157 bytes: Vec::new(),
158 element: None,
159 is_seq: false,
160 };
161 sink.atom(other, state)
162 }
163 }
164 }
165
166 #[inline]
167 fn __private_borrowed_atom_into(
168 out: &mut Option<Self>,
169 atom: Atom<'de>,
170 state: &mut State,
171 ) -> Result<(), Error> {
172 Self::__private_atom_into(out, atom, state)
174 }
175}
176
177impl Via<BString> for Box<BStr> {
178 #[inline]
179 fn convert(value: BString) -> Result<Self, Error> {
180 Ok(Box::from(Vec::from(value).into_boxed_slice()))
181 }
182}
183
184deserialize_via! {
185 [] Box<BStr> => BString;
186}
187
188impl BytesBufImpl for BString {
190 #[inline]
191 fn bytes(&self) -> &[u8] {
192 self.as_slice()
193 }
194
195 #[inline]
196 fn from_vec(bytes: Vec<u8>) -> Result<Self, Error> {
197 Ok(BString::from(bytes))
198 }
199
200 #[inline]
201 fn deserialize_into<'a, 'de>(
202 out: &'a mut Option<Self>,
203 state: &mut State,
204 ) -> SinkHandle<'a, 'de> {
205 Deserialize::deserialize_into(out, state)
206 }
207}
208
209encoding_adapter!([] BString);
210
211impl<'de: 'a, 'a> Sink<'de> for SlotWrapper<&'a BStr> {
212 fn expecting(&self) -> Cow<'_, str> {
213 Cow::Borrowed("borrowed byte string")
214 }
215
216 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
217 match atom {
218 Atom::Str(_) | Atom::Lexical(_) | Atom::Bytes(_) => Err(Error::new(
219 ErrorKind::Unexpected,
220 "unexpected owned byte string, expected a borrowed byte string (the data \
221 format or the type buffering the value does not support borrowing)",
222 )),
223 other => self.unexpected_atom(other, state),
224 }
225 }
226
227 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
228 match atom {
229 Atom::Str(ref text) | Atom::Lexical(ref text) if text.is_borrowed() => {
230 **self = text.borrowed_str().map(BStr::new);
231 Ok(())
232 }
233 Atom::Implicit(ref value) if value.text().is_borrowed() => {
234 **self = value.text().borrowed_str().map(BStr::new);
235 Ok(())
236 }
237 Atom::Bytes(ref value) if value.is_borrowed() => {
238 **self = value.borrowed_data().map(BStr::new);
239 Ok(())
240 }
241 other => self.atom(other, state),
242 }
243 }
244}
245
246impl<'de: 'a, 'a> Deserialize<'de> for &'a BStr {
248 fn deserialize_into<'out>(
249 out: &'out mut Option<Self>,
250 _state: &mut State,
251 ) -> SinkHandle<'out, 'de> {
252 SlotWrapper::make_handle(out)
253 }
254}