deser_core/
std_only_impls.rs1use std::ffi::{OsStr, OsString};
5use std::path::{Path, PathBuf};
6use std::sync::{Mutex, OnceLock, RwLock};
7
8use alloc::borrow::Cow;
9use alloc::boxed::Box;
10use alloc::string::String;
11
12use crate::adapters::Same;
13use crate::de::impls::{Via, deserialize_via, via_handle};
14use crate::de::{Deserialize, Sink, SinkHandle};
15use crate::error::{Error, ErrorKind};
16use crate::event::Atom;
17use crate::ser::{Chunk, Describe, Serialize};
18use crate::{State, Text};
19
20make_slot_wrapper!(SlotWrapper);
21
22impl<T: Serialize + Send> Serialize for OnceLock<T> {
26 fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
27 match self.get() {
28 Some(value) => value.serialize(state),
29 None => Ok(Chunk::Atom(Atom::Null)),
30 }
31 }
32
33 fn finish(&self, state: &mut State) -> Result<(), Error> {
34 match self.get() {
35 Some(value) => value.finish(state),
36 None => Ok(()),
37 }
38 }
39
40 fn is_optional(&self) -> bool {
41 self.get().is_none()
42 }
43
44 fn container_shape(&self) -> crate::ContainerShape {
45 match self.get() {
46 Some(value) => value.container_shape(),
47 None => crate::ContainerShape::new(),
48 }
49 }
50
51 fn describe(&self, d: &mut dyn Describe) {
52 match self.get() {
53 Some(value) => {
54 d.some();
55 value.describe(d);
56 }
57 None => d.none(),
58 }
59 }
60}
61
62impl<T: Send> Via<Option<T>> for OnceLock<T> {
63 #[inline]
64 fn convert(value: Option<T>) -> Result<Self, Error> {
65 Ok(match value {
66 Some(value) => OnceLock::from(value),
67 None => OnceLock::new(),
68 })
69 }
70}
71
72impl<'de, T: Deserialize<'de>> Deserialize<'de> for OnceLock<T> {
74 fn deserialize_into<'out>(
75 out: &'out mut Option<Self>,
76 state: &mut State,
77 ) -> SinkHandle<'out, 'de> {
78 via_handle::<Option<T>, Self, Same>(out, state)
79 }
80
81 fn initial_value() -> Option<Self> {
82 Some(OnceLock::new())
83 }
84}
85
86impl Serialize for Path {
91 begin_without_finish!();
92
93 fn serialize(&self, _state: &mut State) -> Result<Chunk<'_>, Error> {
94 match self.to_str() {
95 Some(value) => Ok(Chunk::Atom(Atom::Str(Text::borrowed(value)))),
96 None => Err(Error::new(
97 ErrorKind::Unexpected,
98 "path contains invalid UTF-8 characters",
99 )),
100 }
101 }
102}
103
104impl Serialize for PathBuf {
105 begin_without_finish!();
106
107 fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
108 self.as_path().serialize(state)
109 }
110}
111
112impl<'de> Sink<'de> for SlotWrapper<PathBuf> {
113 fn expecting(&self) -> Cow<'_, str> {
114 Cow::Borrowed("path")
115 }
116
117 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
118 match atom {
119 Atom::Str(value) => {
120 **self = Some(PathBuf::from(value.into_owned()));
121 Ok(())
122 }
123 other => self.unexpected_atom(other, state),
124 }
125 }
126}
127
128impl<'de> Deserialize<'de> for PathBuf {
129 fn deserialize_into<'out>(
130 out: &'out mut Option<Self>,
131 _state: &mut State,
132 ) -> SinkHandle<'out, 'de> {
133 SlotWrapper::make_handle(out)
134 }
135
136 #[inline]
137 fn __private_atom_into(
138 out: &mut Option<Self>,
139 atom: Atom,
140 state: &mut State,
141 ) -> Result<(), Error> {
142 let sink = SlotWrapper::wrap(out);
143 sink.atom(atom, state)?;
144 sink.finish(state)
145 }
146
147 #[inline]
148 fn __private_borrowed_atom_into(
149 out: &mut Option<Self>,
150 atom: Atom<'de>,
151 state: &mut State,
152 ) -> Result<(), Error> {
153 Self::__private_atom_into(out, atom, state)
154 }
155}
156
157impl Via<PathBuf> for Box<Path> {
158 #[inline]
159 fn convert(value: PathBuf) -> Result<Self, Error> {
160 Ok(value.into_boxed_path())
161 }
162}
163
164deserialize_via! {
165 [] Box<Path> => PathBuf;
166}
167
168impl Serialize for OsStr {
173 begin_without_finish!();
174
175 fn serialize(&self, _state: &mut State) -> Result<Chunk<'_>, Error> {
176 match self.to_str() {
177 Some(value) => Ok(Chunk::Atom(Atom::Str(Text::borrowed(value)))),
178 None => Err(Error::new(
179 ErrorKind::Unexpected,
180 "OS string contains invalid UTF-8 characters",
181 )),
182 }
183 }
184}
185
186impl Serialize for OsString {
187 begin_without_finish!();
188
189 fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
190 self.as_os_str().serialize(state)
191 }
192}
193
194impl Via<String> for OsString {
195 #[inline]
196 fn convert(value: String) -> Result<Self, Error> {
197 Ok(OsString::from(value))
198 }
199}
200
201impl Via<OsString> for Box<OsStr> {
202 #[inline]
203 fn convert(value: OsString) -> Result<Self, Error> {
204 Ok(value.into_boxed_os_str())
205 }
206}
207
208deserialize_via! {
209 [] OsString => String;
210 [] Box<OsStr> => OsString;
211}
212
213impl<T: Send> Via<T> for Mutex<T> {
220 #[inline]
221 fn convert(value: T) -> Result<Self, Error> {
222 Ok(Mutex::new(value))
223 }
224}
225
226impl<T: Send> Via<T> for RwLock<T> {
227 #[inline]
228 fn convert(value: T) -> Result<Self, Error> {
229 Ok(RwLock::new(value))
230 }
231}
232
233deserialize_via! {
234 [T: Deserialize<'de>] Mutex<T> => T;
235 [T: Deserialize<'de>] RwLock<T> => T;
236}