Skip to main content

java_mapping_serde/de/
visit.rs

1//! Mapping visit traits.
2
3use core::fmt::{Display, Formatter};
4
5use crate::de::Deserializer;
6
7use super::Error;
8
9#[inline]
10fn display_from_fn<F>(f: F) -> impl Display
11where
12    F: Fn(&mut Formatter<'_>) -> core::fmt::Result,
13{
14    struct FromFn<F> {
15        inner: F,
16    }
17
18    impl<F> Display for FromFn<F>
19    where
20        F: Fn(&mut Formatter<'_>) -> core::fmt::Result,
21    {
22        #[inline]
23        fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
24            (self.inner)(f)
25        }
26    }
27
28    FromFn { inner: f }
29}
30
31/// Visitors for visiting a single item in a mapping file.
32pub trait Visitor<'de>: Sized {
33    /// The returned value type.
34    type Value;
35
36    /// Expecting item content, for error messages.
37    fn expecting(&self, f: &mut Formatter<'_>) -> core::fmt::Result;
38
39    /// Visits a possibly multi-line comment.
40    fn visit_comment<E>(self, value: &str) -> Result<Self::Value, E>
41    where
42        E: Error,
43    {
44        let _ = value;
45        Err(E::invalid_type(
46            "comment",
47            display_from_fn(|f| self.expecting(f)),
48        ))
49    }
50
51    /// Visits a possibly multi-line comment with borrowed lifetime.
52    ///
53    /// **Never** implement this method only but not `visit_comment`, unless the format deserializer guarantees so.
54    /// By default this forwards to `visit_comment`.
55    #[inline]
56    fn visit_comment_borrowed<E>(self, value: &'de str) -> Result<Self::Value, E>
57    where
58        E: Error,
59    {
60        self.visit_comment(value)
61    }
62
63    /// Visits a class.
64    fn visit_class<'b, A>(self, access: A) -> Result<Self::Value, A::Error>
65    where
66        A: ClassAccess<'de, 'b>,
67    {
68        drop(access);
69        Err(A::Error::invalid_type(
70            "class",
71            display_from_fn(|f| self.expecting(f)),
72        ))
73    }
74
75    /// Visits a class with borrowed lifetime.
76    ///
77    /// **Never** implement this method only but not `visit_class`, unless the format deserializer guarantees so.
78    /// By default this forwards to `visit_class`.
79    #[inline]
80    fn visit_class_borrowed<A>(self, access: A) -> Result<Self::Value, A::Error>
81    where
82        A: ClassAccess<'de, 'de>,
83    {
84        self.visit_class(access)
85    }
86
87    /// Visits a field.
88    fn visit_field<'b, A>(self, access: A) -> Result<Self::Value, A::Error>
89    where
90        A: FieldAccess<'de, 'b>,
91    {
92        drop(access);
93        Err(A::Error::invalid_type(
94            "field",
95            display_from_fn(|f| self.expecting(f)),
96        ))
97    }
98
99    /// Visits a field with borrowed lifetime.
100    ///
101    /// **Never** implement this method only but not `visit_field`, unless the format deserializer guarantees so.
102    /// By default this forwards to `visit_field`.
103    #[inline]
104    fn visit_field_borrowed<A>(self, access: A) -> Result<Self::Value, A::Error>
105    where
106        A: FieldAccess<'de, 'de>,
107    {
108        self.visit_field(access)
109    }
110
111    /// Visits a method.
112    fn visit_method<'b, A>(self, access: A) -> Result<Self::Value, A::Error>
113    where
114        A: MethodAccess<'de, 'b>,
115    {
116        drop(access);
117        Err(A::Error::invalid_type(
118            "method",
119            display_from_fn(|f| self.expecting(f)),
120        ))
121    }
122
123    /// Visits a method argument with borrowed lifetime.
124    ///
125    /// **Never** implement this method only but not `visit_method`, unless the format deserializer guarantees so.
126    /// By default this forwards to `visit_method`.
127    #[inline]
128    fn visit_method_borrowed<A>(self, access: A) -> Result<Self::Value, A::Error>
129    where
130        A: MethodAccess<'de, 'de>,
131    {
132        self.visit_method(access)
133    }
134
135    /// Visits a method argument.
136    fn visit_method_arg<'b, A>(self, access: A) -> Result<Self::Value, A::Error>
137    where
138        A: MethodArgAccess<'de, 'b>,
139    {
140        drop(access);
141        Err(A::Error::invalid_type(
142            "method argument",
143            display_from_fn(|f| self.expecting(f)),
144        ))
145    }
146
147    /// Visits a method argument with borrowed lifetime.
148    ///
149    /// **Never** implement this method only but not `visit_method_arg`, unless the format deserializer guarantees so.
150    /// By default this forwards to `visit_method_arg`.
151    #[inline]
152    fn visit_method_arg_borrowed<A>(self, access: A) -> Result<Self::Value, A::Error>
153    where
154        A: MethodArgAccess<'de, 'de>,
155    {
156        self.visit_method_arg(access)
157    }
158
159    /// Visits a method variable.
160    fn visit_method_var<'b, A>(self, access: A) -> Result<Self::Value, A::Error>
161    where
162        A: MethodVarAccess<'de, 'b>,
163    {
164        drop(access);
165        Err(A::Error::invalid_type(
166            "method variable",
167            display_from_fn(|f| self.expecting(f)),
168        ))
169    }
170
171    /// Visits a method variable with borrowed lifetime.
172    ///
173    /// **Never** implement this method only but not `visit_method_var`, unless the format deserializer guarantees so.
174    /// By default this forwards to `visit_method_var`.
175    #[inline]
176    fn visit_method_var_borrowed<A>(self, access: A) -> Result<Self::Value, A::Error>
177    where
178        A: MethodVarAccess<'de, 'de>,
179    {
180        self.visit_method_var(access)
181    }
182}
183
184/// Class name and content accessor.
185pub trait ClassAccess<'de, 's> {
186    /// Error type.
187    type Error: Error;
188
189    /// Type of deserializer of the element's contents.
190    type ContentDeserializer: Deserializer<'de, Error = Self::Error>;
191
192    /// Source name in internal form of binary name.
193    fn src(&self) -> &'s str;
194
195    /// Destination names in internal form of binary name.
196    fn dst(&self) -> impl Iterator<Item = &'s str>;
197
198    /// Returns the content deserializer for further deserialization of this class.
199    fn content(self) -> Self::ContentDeserializer;
200}
201
202/// Field name, desc and comment accessor.
203pub trait FieldAccess<'de, 's> {
204    /// Error type.
205    type Error: Error;
206
207    /// Type of deserializer of the element's contents.
208    type ContentDeserializer: Deserializer<'de, Error = Self::Error>;
209
210    /// Source simple name.
211    fn src(&self) -> &'s str;
212
213    /// Destination simple names.
214    fn dst(&self) -> impl Iterator<Item = &'s str>;
215
216    /// Descriptor of this field as `FieldType` shown in JVMS.
217    fn desc(&self) -> Option<&'s str>;
218
219    /// Descriptor of this field's destinations as `FieldType` shown in JVMS.
220    fn dst_desc(&self) -> Option<impl Iterator<Item = &'s str>>;
221
222    /// Returns the content deserializer for further deserialization of this field.
223    ///
224    /// It may only contain comments.
225    fn content(self) -> Self::ContentDeserializer;
226}
227
228/// Method name, desc and content accessor.
229pub trait MethodAccess<'de, 's> {
230    /// Error type.
231    type Error: Error;
232
233    /// Type of deserializer of the element's contents.
234    type ContentDeserializer: Deserializer<'de, Error = Self::Error>;
235
236    /// Source simple name.
237    fn src(&self) -> &'s str;
238
239    /// Destination simple names.
240    fn dst(&self) -> impl Iterator<Item = &'s str>;
241
242    /// Descriptor of this method.
243    fn desc(&self) -> Option<&'s str>;
244
245    /// Descriptor of this field's destinations.
246    fn dst_desc(&self) -> Option<impl Iterator<Item = &'s str>>;
247
248    /// Returns the content deserializer for further deserialization of this method.
249    fn content(self) -> Self::ContentDeserializer;
250}
251
252/// Method argument name, pos, slot and comment accessor.
253pub trait MethodArgAccess<'de, 's> {
254    /// Error type.
255    type Error: Error;
256
257    /// Type of deserializer of the element's contents.
258    type ContentDeserializer: Deserializer<'de, Error = Self::Error>;
259
260    /// Source simple name.
261    fn src(&self) -> Option<&'s str>;
262
263    /// Destination simple names.
264    fn dst(&self) -> Option<impl Iterator<Item = &'s str>>;
265
266    /// The position of this argument starts from zero, and increase by one.
267    fn pos(&self) -> Option<usize>;
268
269    /// The local variable index of this parameter in the current method.
270    ///
271    /// Starts at zero for static methods and one otherwise, increase by 1, or by 2 if it's a double-wide primitive.
272    ///
273    /// Also known as `slot`.
274    #[doc(alias = "slot")]
275    fn lv_index(&self) -> Option<usize>;
276
277    /// Returns the content deserializer for further deserialization of this method.
278    ///
279    /// It may only contain comments.
280    fn content(self) -> Self::ContentDeserializer;
281}
282
283/// Method argument name, pos, slot and comment accessor.
284pub trait MethodVarAccess<'de, 's> {
285    /// Error type.
286    type Error: Error;
287
288    /// Type of deserializer of the element's contents.
289    type ContentDeserializer: Deserializer<'de, Error = Self::Error>;
290
291    /// Source simple name.
292    fn src(&self) -> Option<&'s str>;
293
294    /// Destination simple names.
295    fn dst(&self) -> Option<impl Iterator<Item = &'s str>>;
296
297    /// The local variable index of this variable in the current method.
298    ///
299    /// Starts at the last parameter's slot plus wideness, and increase by 1, or by 2 if it's a double-wide primitive.
300    ///
301    /// Also known as `slot`.
302    #[doc(alias = "slot")]
303    fn lv_index(&self) -> Option<usize>;
304
305    /// The index of variable in the method's local variable table.
306    fn lvt_row_index(&self) -> Option<usize>;
307
308    /// > Required for cases when the lvIndex alone doesn't uniquely identify a local variable.
309    /// > This is the case when variables get re-defined later on, in which case most decompilers opt to
310    /// > not re-define the existing var, but instead generate a new one (with both sharing the same `lv_index`).
311    ///
312    /// (from `mapping-io`)
313    fn op_idx(&self) -> Option<(usize, Option<usize>)>;
314
315    /// Returns the content deserializer for further deserialization of this method.
316    ///
317    /// It may only contain comments.
318    fn content(self) -> Self::ContentDeserializer;
319}