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}