Skip to main content

java_mapping_serde/
ser.rs

1//! Serialization.
2
3use core::{
4    convert::Infallible,
5    fmt::{Debug, Display},
6    marker::PhantomData,
7};
8
9use crate::Deserializer;
10
11mod r#impl;
12
13/// Error type used by a serializer.
14pub trait Error: core::error::Error + Sized {
15    /// A general error message during serialization.
16    fn custom<T>(msg: T) -> Self
17    where
18        T: Display;
19
20    /// Ran into an element type that is not supported by the serializer.
21    fn unsupported_type(ty: impl Display) -> Self {
22        Self::custom(format_args!("unsupported type for serializer: {ty}"))
23    }
24
25    /// One or more fields are missing in the provided arguments during serialization.
26    fn missing_field(field: impl Display) -> Self {
27        Self::custom(format_args!("missing field for serializer: {field}"))
28    }
29}
30
31/// Type that could be serialized into a mapping file through [`Serializer`].
32pub trait Serialize {
33    /// Serializes this value.
34    fn serialize<S>(&self, serializer: S) -> Result<(), S::Error>
35    where
36        S: Serializer;
37}
38
39impl<T: ?Sized> Serialize for &T
40where
41    T: Serialize,
42{
43    #[inline]
44    fn serialize<S>(&self, serializer: S) -> Result<(), S::Error>
45    where
46        S: Serializer,
47    {
48        T::serialize(self, serializer)
49    }
50}
51
52/// Serializer of a mapping file.
53pub trait Serializer {
54    /// The error type.
55    type Error: Error;
56
57    /// Whether inner classes should be flattened.
58    const FLAT_CLASSES: bool;
59
60    /// Whether the deserializer's class layout matches this serializer's class layout.
61    ///
62    /// By default this compares [`Self::FLAT_CLASSES`] of the two.
63    #[inline]
64    fn layout_matches<'de, D>() -> bool
65    where
66        D: Deserializer<'de> + ?Sized,
67    {
68        D::FLAT_CLASSES == Self::FLAT_CLASSES
69    }
70
71    /// Type returned from [`Serializer::serialize_class`] for class content serialization.
72    type SerializeClass<'a>: Serializer<Error = Self::Error>
73    where
74        Self: 'a;
75
76    /// Type returned from [`Serializer::serialize_field`] for field comment serialization.
77    type SerializeField<'a>: Serializer<Error = Self::Error>
78    where
79        Self: 'a;
80
81    /// Type returned from [`Serializer::serialize_method`] for method arguments, variables and comment serialization.
82    type SerializeMethod<'a>: Serializer<Error = Self::Error>
83    where
84        Self: 'a;
85
86    /// Type returned from [`Serializer::serialize_method_arg`] for method argument comment serialization.
87    type SerializeMethodArg<'a>: Serializer<Error = Self::Error>
88    where
89        Self: 'a;
90
91    /// Type returned from [`Serializer::serialize_method_var`] for method variable comment serialization.
92    type SerializeMethodVar<'a>: Serializer<Error = Self::Error>
93    where
94        Self: 'a;
95
96    /// Serializes a comment literal.
97    fn serialize_comment(&mut self, value: &str) -> Result<(), Self::Error>;
98
99    /// Serializes a class.
100    fn serialize_class<Dst>(
101        &mut self,
102        src: &str,
103        dst: Dst,
104    ) -> Result<Self::SerializeClass<'_>, Self::Error>
105    where
106        Dst: IntoIterator<Item: AsRef<str>>;
107
108    /// Serializes a field.
109    fn serialize_field<Dst, DstDesc>(
110        &mut self,
111        src: &str,
112        desc: Option<&str>,
113        dst: Dst,
114        dst_desc: Option<DstDesc>,
115    ) -> Result<Self::SerializeField<'_>, Self::Error>
116    where
117        Dst: IntoIterator<Item: AsRef<str>>,
118        DstDesc: IntoIterator<Item: AsRef<str>>;
119
120    /// Serializes a method.
121    fn serialize_method<Dst, DstDesc>(
122        &mut self,
123        src: &str,
124        desc: Option<&str>,
125        dst: Dst,
126        dst_desc: Option<DstDesc>,
127    ) -> Result<Self::SerializeMethod<'_>, Self::Error>
128    where
129        Dst: IntoIterator<Item: AsRef<str>>,
130        DstDesc: IntoIterator<Item: AsRef<str>>;
131
132    /// Serializes a method argument.
133    fn serialize_method_arg<Dst>(
134        &mut self,
135        src: Option<&str>,
136        dst: Option<Dst>,
137        pos: Option<usize>,
138        lv_index: Option<usize>,
139    ) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
140    where
141        Dst: IntoIterator<Item: AsRef<str>>;
142
143    /// Serializes a method variable.
144    fn serialize_method_var<Dst>(
145        &mut self,
146        src: Option<&str>,
147        dst: Option<Dst>,
148        lv_index: Option<usize>,
149        lvt_row_index: Option<usize>,
150        op_idx: Option<(usize, Option<usize>)>,
151    ) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
152    where
153        Dst: IntoIterator<Item: AsRef<str>>;
154}
155
156impl<T> Serializer for &mut T
157where
158    T: Serializer,
159{
160    type Error = T::Error;
161
162    const FLAT_CLASSES: bool = T::FLAT_CLASSES;
163
164    #[inline]
165    fn layout_matches<'de, D>() -> bool
166    where
167        D: Deserializer<'de> + ?Sized,
168    {
169        T::layout_matches::<'de, D>()
170    }
171
172    type SerializeClass<'a>
173        = T::SerializeClass<'a>
174    where
175        Self: 'a;
176
177    type SerializeField<'a>
178        = T::SerializeField<'a>
179    where
180        Self: 'a;
181
182    type SerializeMethod<'a>
183        = T::SerializeMethod<'a>
184    where
185        Self: 'a;
186
187    type SerializeMethodArg<'a>
188        = T::SerializeMethodArg<'a>
189    where
190        Self: 'a;
191
192    type SerializeMethodVar<'a>
193        = T::SerializeMethodVar<'a>
194    where
195        Self: 'a;
196
197    #[inline]
198    fn serialize_comment(&mut self, value: &str) -> Result<(), Self::Error> {
199        T::serialize_comment(self, value)
200    }
201
202    #[inline]
203    fn serialize_class<Dst>(
204        &mut self,
205        src: &str,
206        dst: Dst,
207    ) -> Result<Self::SerializeClass<'_>, Self::Error>
208    where
209        Dst: IntoIterator<Item: AsRef<str>>,
210    {
211        T::serialize_class(self, src, dst)
212    }
213
214    #[inline]
215    fn serialize_field<Dst, DstDesc>(
216        &mut self,
217        src: &str,
218        desc: Option<&str>,
219        dst: Dst,
220        dst_desc: Option<DstDesc>,
221    ) -> Result<Self::SerializeField<'_>, Self::Error>
222    where
223        Dst: IntoIterator<Item: AsRef<str>>,
224        DstDesc: IntoIterator<Item: AsRef<str>>,
225    {
226        T::serialize_field(self, src, desc, dst, dst_desc)
227    }
228
229    #[inline]
230    fn serialize_method<Dst, DstDesc>(
231        &mut self,
232        src: &str,
233        desc: Option<&str>,
234        dst: Dst,
235        dst_desc: Option<DstDesc>,
236    ) -> Result<Self::SerializeMethod<'_>, Self::Error>
237    where
238        Dst: IntoIterator<Item: AsRef<str>>,
239        DstDesc: IntoIterator<Item: AsRef<str>>,
240    {
241        T::serialize_method(self, src, desc, dst, dst_desc)
242    }
243
244    #[inline]
245    fn serialize_method_arg<Dst>(
246        &mut self,
247        src: Option<&str>,
248        dst: Option<Dst>,
249        pos: Option<usize>,
250        lv_index: Option<usize>,
251    ) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
252    where
253        Dst: IntoIterator<Item: AsRef<str>>,
254    {
255        T::serialize_method_arg(self, src, dst, pos, lv_index)
256    }
257
258    #[inline]
259    fn serialize_method_var<Dst>(
260        &mut self,
261        src: Option<&str>,
262        dst: Option<Dst>,
263        lv_index: Option<usize>,
264        lvt_row_index: Option<usize>,
265        op_idx: Option<(usize, Option<usize>)>,
266    ) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
267    where
268        Dst: IntoIterator<Item: AsRef<str>>,
269    {
270        T::serialize_method_var(self, src, dst, lv_index, lvt_row_index, op_idx)
271    }
272}
273
274enum Unconstructable {}
275
276/// Helper type for implementing a `Serializer` that does not support serializing one of the element types.
277#[allow(missing_debug_implementations)]
278pub struct Impossible<Err>(Unconstructable, PhantomData<Err>);
279
280impl<Err> Serializer for Impossible<Err>
281where
282    Err: Error,
283{
284    type Error = Err;
285
286    const FLAT_CLASSES: bool = false;
287
288    #[inline]
289    fn layout_matches<'de, D>() -> bool
290    where
291        D: Deserializer<'de> + ?Sized,
292    {
293        true
294    }
295
296    type SerializeClass<'a>
297        = Self
298    where
299        Self: 'a;
300
301    type SerializeField<'a>
302        = Self
303    where
304        Self: 'a;
305
306    type SerializeMethod<'a>
307        = Self
308    where
309        Self: 'a;
310
311    type SerializeMethodArg<'a>
312        = Self
313    where
314        Self: 'a;
315
316    type SerializeMethodVar<'a>
317        = Self
318    where
319        Self: 'a;
320
321    fn serialize_comment(&mut self, _value: &str) -> Result<(), Self::Error> {
322        Err(Err::unsupported_type("comment"))
323    }
324
325    fn serialize_class<Dst>(
326        &mut self,
327        _src: &str,
328        _dst: Dst,
329    ) -> Result<Self::SerializeClass<'_>, Self::Error>
330    where
331        Dst: IntoIterator<Item: AsRef<str>>,
332    {
333        Err(Err::unsupported_type("class"))
334    }
335
336    fn serialize_field<Dst, DstDesc>(
337        &mut self,
338        _src: &str,
339        _desc: Option<&str>,
340        _dst: Dst,
341        _dst_desc: Option<DstDesc>,
342    ) -> Result<Self::SerializeField<'_>, Self::Error>
343    where
344        Dst: IntoIterator<Item: AsRef<str>>,
345        DstDesc: IntoIterator<Item: AsRef<str>>,
346    {
347        Err(Err::unsupported_type("field"))
348    }
349
350    fn serialize_method<Dst, DstDesc>(
351        &mut self,
352        _src: &str,
353        _desc: Option<&str>,
354        _dst: Dst,
355        _dst_desc: Option<DstDesc>,
356    ) -> Result<Self::SerializeMethod<'_>, Self::Error>
357    where
358        Dst: IntoIterator<Item: AsRef<str>>,
359        DstDesc: IntoIterator<Item: AsRef<str>>,
360    {
361        Err(Err::unsupported_type("method"))
362    }
363
364    fn serialize_method_arg<Dst>(
365        &mut self,
366        _src: Option<&str>,
367        _dst: Option<Dst>,
368        _pos: Option<usize>,
369        _lv_index: Option<usize>,
370    ) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
371    where
372        Dst: IntoIterator<Item: AsRef<str>>,
373    {
374        Err(Err::unsupported_type("method argument"))
375    }
376
377    fn serialize_method_var<Dst>(
378        &mut self,
379        _src: Option<&str>,
380        _dst: Option<Dst>,
381        _lv_index: Option<usize>,
382        _lvt_row_index: Option<usize>,
383        _op_idx: Option<(usize, Option<usize>)>,
384    ) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
385    where
386        Dst: IntoIterator<Item: AsRef<str>>,
387    {
388        Err(Err::unsupported_type("method variable"))
389    }
390}
391
392/// Helper type for implementing a `Serializer` that skips serializing one of the element types.
393pub struct Skip<Err>(PhantomData<Err>);
394
395impl<Err> Skip<Err> {
396    /// Creates a new skip helper.
397    #[inline]
398    pub const fn new() -> Self {
399        Self(PhantomData)
400    }
401}
402
403impl<Err> Default for Skip<Err> {
404    #[inline]
405    fn default() -> Self {
406        Self::new()
407    }
408}
409
410impl<Err> Debug for Skip<Err> {
411    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
412        f.debug_tuple("Skip").finish()
413    }
414}
415
416impl<Err> Serializer for Skip<Err>
417where
418    Err: Error,
419{
420    type Error = Err;
421
422    const FLAT_CLASSES: bool = false;
423
424    #[inline]
425    fn layout_matches<'de, D>() -> bool
426    where
427        D: Deserializer<'de> + ?Sized,
428    {
429        true
430    }
431
432    type SerializeClass<'a>
433        = Self
434    where
435        Self: 'a;
436
437    type SerializeField<'a>
438        = Self
439    where
440        Self: 'a;
441
442    type SerializeMethod<'a>
443        = Self
444    where
445        Self: 'a;
446
447    type SerializeMethodArg<'a>
448        = Self
449    where
450        Self: 'a;
451
452    type SerializeMethodVar<'a>
453        = Self
454    where
455        Self: 'a;
456
457    #[inline]
458    fn serialize_comment(&mut self, _value: &str) -> Result<(), Self::Error> {
459        Ok(())
460    }
461
462    #[inline]
463    fn serialize_class<Dst>(
464        &mut self,
465        _src: &str,
466        _dst: Dst,
467    ) -> Result<Self::SerializeClass<'_>, Self::Error>
468    where
469        Dst: IntoIterator<Item: AsRef<str>>,
470    {
471        Ok(Self::new())
472    }
473
474    #[inline]
475    fn serialize_field<Dst, DstDesc>(
476        &mut self,
477        _src: &str,
478        _desc: Option<&str>,
479        _dst: Dst,
480        _dst_desc: Option<DstDesc>,
481    ) -> Result<Self::SerializeField<'_>, Self::Error>
482    where
483        Dst: IntoIterator<Item: AsRef<str>>,
484        DstDesc: IntoIterator<Item: AsRef<str>>,
485    {
486        Ok(Self::new())
487    }
488
489    #[inline]
490    fn serialize_method<Dst, DstDesc>(
491        &mut self,
492        _src: &str,
493        _desc: Option<&str>,
494        _dst: Dst,
495        _dst_desc: Option<DstDesc>,
496    ) -> Result<Self::SerializeMethod<'_>, Self::Error>
497    where
498        Dst: IntoIterator<Item: AsRef<str>>,
499        DstDesc: IntoIterator<Item: AsRef<str>>,
500    {
501        Ok(Self::new())
502    }
503
504    #[inline]
505    fn serialize_method_arg<Dst>(
506        &mut self,
507        _src: Option<&str>,
508        _dst: Option<Dst>,
509        _pos: Option<usize>,
510        _lv_index: Option<usize>,
511    ) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
512    where
513        Dst: IntoIterator<Item: AsRef<str>>,
514    {
515        Ok(Self::new())
516    }
517
518    #[inline]
519    fn serialize_method_var<Dst>(
520        &mut self,
521        _src: Option<&str>,
522        _dst: Option<Dst>,
523        _lv_index: Option<usize>,
524        _lvt_row_index: Option<usize>,
525        _op_idx: Option<(usize, Option<usize>)>,
526    ) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
527    where
528        Dst: IntoIterator<Item: AsRef<str>>,
529    {
530        Ok(Self::new())
531    }
532}
533
534impl Error for Infallible {
535    fn custom<T>(_msg: T) -> Self
536    where
537        T: Display,
538    {
539        unreachable!()
540    }
541}