1use alloc::borrow::Cow;
3use alloc::string::String;
4use core::fmt;
5
6use deser_core::State;
7use deser_core::de::{Deserialize, OwnedSink, Sink, SinkHandle};
8use deser_core::ser::{Describe, Emit, Serialize};
9use deser_core::{Atom, ContainerShape, Error};
10
11#[derive(Debug, Default, Clone)]
16pub(crate) struct ClassName(pub(crate) Option<String>);
17
18#[derive(Debug, Default, Clone)]
20pub(crate) struct PropertyVisibility(pub(crate) Option<Visibility>);
21
22#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
30pub enum Visibility {
31 #[default]
33 Public,
34 Protected,
36 Private(String),
38}
39
40pub fn take_class(state: &mut State) -> Option<String> {
55 state.take_event::<ClassName>().and_then(|class| class.0)
58}
59
60pub fn set_class<S: Into<String>>(state: &mut State, class: S) {
68 state.event_mut::<ClassName>().0 = Some(class.into());
69}
70
71pub fn take_visibility(state: &mut State) -> Option<Visibility> {
76 state
77 .take_event::<PropertyVisibility>()
78 .and_then(|visibility| visibility.0)
79}
80
81pub fn set_visibility(state: &mut State, visibility: Visibility) {
86 state.event_mut::<PropertyVisibility>().0 = Some(visibility);
87}
88
89#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
110pub struct Object<T> {
111 pub class: Option<String>,
113 pub value: T,
115}
116
117impl<T> Object<T> {
118 pub fn new<S: Into<String>>(class: S, value: T) -> Object<T> {
120 Object {
121 class: Some(class.into()),
122 value,
123 }
124 }
125
126 pub fn into_inner(self) -> T {
128 self.value
129 }
130}
131
132impl<T: fmt::Debug> fmt::Debug for Object<T> {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 match self.class {
135 Some(ref class) => {
136 write!(f, "{} ", class)?;
137 fmt::Debug::fmt(&self.value, f)
138 }
139 None => fmt::Debug::fmt(&self.value, f),
140 }
141 }
142}
143
144impl<T: Serialize> Serialize for Object<T> {
145 fn serialize<'a>(this: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
146 let emit = T::serialize(&this.value, state)?;
149 if let Some(ref class) = this.class {
150 set_class(state, class.as_str());
151 }
152 Ok(emit)
153 }
154
155 fn finish(this: &Self, state: &mut State) -> Result<(), Error> {
156 T::finish(&this.value, state)
157 }
158
159 fn is_optional(this: &Self) -> bool {
160 T::is_optional(&this.value)
161 }
162
163 fn container_shape(this: &Self) -> ContainerShape {
164 T::container_shape(&this.value)
165 }
166
167 fn describe(this: &Self, d: &mut dyn Describe) {
168 T::describe(&this.value, d)
169 }
170}
171
172impl<'de, T: Deserialize<'de>> Deserialize<'de> for Object<T> {
173 fn deserialize_into<'out>(
174 out: &'out mut Option<Self>,
175 state: &mut State,
176 ) -> SinkHandle<'out, 'de> {
177 SinkHandle::arena(
178 ObjectSink {
179 out,
180 slot: None,
181 compound: None,
182 class: None,
183 },
184 state,
185 )
186 }
187
188 fn expecting() -> Cow<'static, str> {
189 T::expecting()
190 }
191
192 fn describe_type(d: &mut dyn Describe) {
193 T::describe_type(d)
194 }
195}
196
197struct ObjectSink<'a, 'de, T> {
198 out: &'a mut Option<Object<T>>,
199 slot: Option<T>,
202 compound: Option<OwnedSink<'de, T>>,
203 class: Option<String>,
204}
205
206impl<'a, 'de, T: Deserialize<'de>> ObjectSink<'a, 'de, T> {
207 fn compound(&mut self, state: &mut State) -> &mut dyn Sink<'de> {
208 self.compound
209 .get_or_insert_with(|| OwnedSink::deserialize(state))
210 .get_mut()
211 }
212}
213
214impl<'a, 'de, T: Deserialize<'de>> Sink<'de> for ObjectSink<'a, 'de, T> {
215 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
216 self.class = take_class(state);
217 let mut sink = T::deserialize_into(&mut self.slot, state);
218 sink.atom(atom, state)?;
219 sink.finish(state)
220 }
221
222 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
223 self.class = take_class(state);
224 let mut sink = T::deserialize_into(&mut self.slot, state);
225 sink.borrowed_atom(atom, state)?;
226 sink.finish(state)
227 }
228
229 fn map(&mut self, state: &mut State) -> Result<(), Error> {
230 self.class = take_class(state);
231 self.compound(state).map(state)
232 }
233
234 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
235 self.class = take_class(state);
236 self.compound(state).seq(state)
237 }
238
239 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
240 self.compound(state).next_key(state)
241 }
242
243 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
244 self.compound(state).next_value(state)
245 }
246
247 fn value_for_key(
248 &mut self,
249 key: &str,
250 state: &mut State,
251 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
252 self.compound(state).value_for_key(key, state)
253 }
254
255 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
256 match self.compound {
257 Some(ref mut compound) => compound.get_mut().recover(err, state),
258 None => Err(err),
259 }
260 }
261
262 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
263 let value = match self.compound {
264 Some(ref mut compound) => {
265 compound.get_mut().finish(state)?;
266 compound.take()
267 }
268 None => self.slot.take(),
269 };
270 let class = self.class.take();
271 *self.out = value.map(|value| Object { class, value });
272 Ok(())
273 }
274
275 fn expecting(&self) -> Cow<'_, str> {
276 if let Some(ref compound) = self.compound {
277 return compound.get().expecting();
278 }
279 T::expecting()
280 }
281}