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