facet_format/parser.rs
1extern crate alloc;
2
3use crate::ParseError;
4use alloc::collections::VecDeque;
5use facet_reflect::Span;
6
7/// Opaque token returned by [`FormatParser::save`].
8///
9/// This token can be passed to [`FormatParser::restore`] to replay
10/// all events that were consumed since the save point.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct SavePoint(pub u64);
13
14impl SavePoint {
15 /// Create a new save point with the given ID.
16 pub fn new(id: u64) -> Self {
17 Self(id)
18 }
19}
20
21/// Streaming parser for a specific wire format.
22pub trait FormatParser<'de> {
23 /// Read the next parse event, or `None` if the input is exhausted.
24 ///
25 /// Returns `Ok(None)` at end-of-input (EOF). For formats like TOML where
26 /// structs can be "reopened" (fields added after the struct was previously
27 /// exited), callers should continue processing until EOF rather than
28 /// stopping at `StructEnd`.
29 ///
30 /// If [`restore`](Self::restore) was called, events are first replayed
31 /// from the internal buffer before reading new events from the input.
32 fn next_event(&mut self) -> Result<Option<crate::ParseEvent<'de>>, ParseError>;
33
34 /// Read multiple parse events into a deque, returning the number of events read.
35 ///
36 /// This is an optimization for parsers that can produce multiple events efficiently
37 /// in a single call, amortizing function call overhead and improving cache locality.
38 ///
39 /// Returns `Ok(0)` at end-of-input (EOF).
40 ///
41 /// The default implementation calls `next_event` repeatedly up to `limit` times.
42 /// Parsers can override this for better performance.
43 fn next_events(
44 &mut self,
45 buf: &mut VecDeque<crate::ParseEvent<'de>>,
46 limit: usize,
47 ) -> Result<usize, ParseError> {
48 let mut count = 0;
49 while count < limit {
50 match self.next_event()? {
51 Some(event) => {
52 buf.push_back(event);
53 count += 1;
54 }
55 None => break,
56 }
57 }
58 Ok(count)
59 }
60
61 /// Peek at the next event without consuming it, or `None` if at EOF.
62 fn peek_event(&mut self) -> Result<Option<crate::ParseEvent<'de>>, ParseError>;
63
64 /// Skip the current value (for unknown fields, etc.).
65 fn skip_value(&mut self) -> Result<(), ParseError>;
66
67 /// Save the current parser position and start recording events.
68 ///
69 /// Returns a [`SavePoint`] token. All events returned by [`next_event`](Self::next_event)
70 /// after this call are recorded internally. Call [`restore`](Self::restore) with this
71 /// token to replay all recorded events.
72 ///
73 /// This is used for untagged enum resolution: save, read ahead to determine
74 /// the variant, then restore and parse with the correct type.
75 fn save(&mut self) -> SavePoint;
76
77 /// Restore to a previous save point, replaying recorded events.
78 ///
79 /// After calling this, subsequent calls to [`next_event`](Self::next_event) will
80 /// first return all events that were recorded since the save point, then
81 /// continue reading from the input.
82 ///
83 /// The save point is consumed - to save again, call [`save`](Self::save).
84 fn restore(&mut self, save_point: SavePoint);
85
86 /// Capture the raw representation of the current value without parsing it.
87 ///
88 /// This is used for types like `RawJson` that want to defer parsing.
89 /// The parser should skip the value and return the raw bytes/string
90 /// from the input.
91 ///
92 /// Returns `Ok(None)` if raw capture is not supported (e.g., streaming mode
93 /// or formats where raw capture doesn't make sense).
94 fn capture_raw(&mut self) -> Result<Option<&'de str>, ParseError> {
95 // Default: not supported
96 self.skip_value()?;
97 Ok(None)
98 }
99
100 /// Returns the raw input bytes, if available.
101 ///
102 /// This is used by the deserializer to implement raw capture when buffering
103 /// events. The deserializer tracks value boundaries using event spans and
104 /// slices the input directly.
105 ///
106 /// Returns `None` for streaming parsers that don't have the full input.
107 fn input(&self) -> Option<&'de [u8]> {
108 None
109 }
110
111 /// Returns the shape of the format's raw capture type (e.g., `RawJson::SHAPE`).
112 ///
113 /// When the deserializer encounters a shape that matches this, it will use
114 /// `capture_raw` to capture the raw representation and store it in a
115 /// `Cow<str>` (the raw type must be a newtype over `Cow<str>`).
116 ///
117 /// Returns `None` if this format doesn't support raw capture types.
118 fn raw_capture_shape(&self) -> Option<&'static facet_core::Shape> {
119 None
120 }
121
122 /// Returns true if this format is self-describing.
123 ///
124 /// Self-describing formats (like JSON, YAML) include type information in the wire format
125 /// and emit `FieldKey` events for struct fields.
126 ///
127 /// Non-self-describing formats (like postcard, bincode) don't include type markers
128 /// and use `OrderedField` events, relying on the driver to provide schema information
129 /// via `hint_struct_fields`.
130 fn is_self_describing(&self) -> bool {
131 true // Default: most formats are self-describing
132 }
133
134 /// Whether the parser relies on `hint_sequence`/`hint_array` to
135 /// disambiguate container syntax (for example Lua's `{}`, which could be
136 /// an empty array or an empty map).
137 ///
138 /// When true, the deserializer bypasses event buffering so hints reach
139 /// the parser before the corresponding events are produced, and the
140 /// parser may reclassify an already-peeked container-start event when a
141 /// hint arrives.
142 fn needs_container_hints(&self) -> bool {
143 false
144 }
145
146 /// Hint to the parser that a struct with the given number of fields is expected.
147 ///
148 /// For non-self-describing formats, this allows the parser to emit the correct
149 /// number of `OrderedField` events followed by `StructEnd`.
150 ///
151 /// Self-describing formats can ignore this hint.
152 fn hint_struct_fields(&mut self, _num_fields: usize) {
153 // Default: ignore (self-describing formats don't need this)
154 }
155
156 /// Hint to the parser what scalar type is expected next.
157 ///
158 /// For non-self-describing formats, this allows the parser to correctly
159 /// decode the next value and emit an appropriate `Scalar` event.
160 ///
161 /// Self-describing formats can ignore this hint (they determine the type
162 /// from the wire format).
163 fn hint_scalar_type(&mut self, _hint: ScalarTypeHint) {
164 // Default: ignore (self-describing formats don't need this)
165 }
166
167 /// Hint to the parser that a sequence (array/Vec) is expected.
168 ///
169 /// For non-self-describing formats, this triggers reading the length prefix
170 /// and setting up sequence state.
171 ///
172 /// Unlike the schema-driven hints above, this is called for *all*
173 /// formats: self-describing formats with ambiguous container syntax (see
174 /// [`needs_container_hints`](Self::needs_container_hints)) use it to
175 /// disambiguate; others can ignore it.
176 fn hint_sequence(&mut self) {
177 // Default: ignore (self-describing formats don't need this)
178 }
179
180 /// Hint to the parser that a byte sequence (`Vec<u8>`, `&[u8]`, etc.) is expected.
181 ///
182 /// For binary formats like postcard that store `Vec<u8>` as raw bytes (varint length
183 /// followed by raw data), this allows bulk reading instead of element-by-element
184 /// deserialization.
185 ///
186 /// If the parser handles this hint, it should emit `Scalar(Bytes(...))` directly.
187 /// If it doesn't support this optimization, it should return `false` and the
188 /// deserializer will fall back to element-by-element deserialization via `hint_sequence`.
189 ///
190 /// Returns `true` if the hint is handled (parser will emit `Scalar(Bytes(...))`),
191 /// `false` otherwise.
192 fn hint_byte_sequence(&mut self) -> bool {
193 // Default: not supported, fall back to element-by-element
194 false
195 }
196
197 /// Hint to the parser that all remaining input bytes should be consumed as a byte slice.
198 ///
199 /// This is used by formats like postcard for trailing opaque payloads where the
200 /// field boundary is "until end of input" rather than a length prefix.
201 ///
202 /// If handled, the parser should emit `Scalar(Bytes(...))` and advance to EOF.
203 /// Returns `true` if handled, `false` to use normal deserialization behavior.
204 fn hint_remaining_byte_sequence(&mut self) -> bool {
205 false
206 }
207
208 /// Hint to the parser that a fixed-size array is expected.
209 ///
210 /// For non-self-describing formats, this tells the parser the array length
211 /// is known at compile time (from the type), so no length prefix is read.
212 /// This differs from `hint_sequence` which reads a length prefix for Vec/slices.
213 ///
214 /// Like [`hint_sequence`](Self::hint_sequence), this is called for *all*
215 /// formats; only parsers that need container disambiguation consume it.
216 fn hint_array(&mut self, _len: usize) {
217 // Default: ignore (self-describing formats don't need this)
218 }
219
220 /// Hint to the parser that an `Option<T>` is expected.
221 ///
222 /// For non-self-describing formats (like postcard), this allows the parser
223 /// to read the discriminant byte and emit either:
224 /// - `Scalar(Null)` for None (discriminant 0x00)
225 /// - Set up state to parse the inner value for Some (discriminant 0x01)
226 ///
227 /// Self-describing formats can ignore this hint (they determine `Option`
228 /// presence from the wire format, e.g., null vs value in JSON).
229 fn hint_option(&mut self) {
230 // Default: ignore (self-describing formats don't need this)
231 }
232
233 /// Hint to the parser that a map is expected.
234 ///
235 /// For non-self-describing formats (like postcard), this allows the parser
236 /// to read the length prefix and set up map state. The parser should then
237 /// emit `SequenceStart` (representing the map entries) followed by pairs of
238 /// key and value events, and finally `SequenceEnd`.
239 ///
240 /// Self-describing formats can ignore this hint (they determine map structure
241 /// from the wire format, e.g., `{...}` in JSON).
242 fn hint_map(&mut self) {
243 // Default: ignore (self-describing formats don't need this)
244 }
245
246 /// Hint to the parser that a dynamic value is expected.
247 ///
248 /// Non-self-describing formats can use this to switch to a self-describing
249 /// encoding for dynamic values (e.g., tagged scalar/array/object).
250 /// Self-describing formats can ignore this hint.
251 fn hint_dynamic_value(&mut self) {
252 // Default: ignore (self-describing formats don't need this)
253 }
254
255 /// Hint to the parser that an enum is expected, providing variant information.
256 ///
257 /// For non-self-describing formats (like postcard), this allows the parser
258 /// to read the variant discriminant (varint) and map it to the variant name,
259 /// and to emit appropriate wrapper events for multi-field variants.
260 ///
261 /// The `variants` slice contains metadata for each variant in declaration order,
262 /// matching the indices used in the wire format.
263 ///
264 /// Self-describing formats can ignore this hint (they include variant names
265 /// in the wire format).
266 fn hint_enum(&mut self, _variants: &[EnumVariantHint]) {
267 // Default: ignore (self-describing formats don't need this)
268 }
269
270 /// Hint to the parser that an opaque scalar type is expected.
271 ///
272 /// For non-self-describing binary formats (like postcard), this allows the parser
273 /// to use format-specific encoding for types like UUID (16 raw bytes), ULID,
274 /// OrderedFloat, etc. that have a more efficient binary representation than
275 /// their string form.
276 ///
277 /// The `type_identifier` is the type's identifier string (e.g., "Uuid", "Ulid",
278 /// "OrderedFloat", `DateTime<Utc>`). The `shape` provides access to inner type
279 /// information (e.g., whether OrderedFloat wraps f32 or f64).
280 ///
281 /// Returns `true` if the parser will handle this type specially (caller should
282 /// expect format-specific `ScalarValue`), or `false` to fall back to standard
283 /// handling (e.g., `hint_scalar_type(String)` for `FromStr` types).
284 ///
285 /// Self-describing formats can ignore this and return `false`.
286 fn hint_opaque_scalar(
287 &mut self,
288 _type_identifier: &'static str,
289 _shape: &'static facet_core::Shape,
290 ) -> bool {
291 // Default: not handled, fall back to standard behavior
292 false
293 }
294
295 /// Returns the source span of the most recently consumed event.
296 ///
297 /// This is used for error reporting - when a deserialization error occurs,
298 /// the span of the last consumed event helps locate the problem in the input.
299 ///
300 /// Parsers that track source positions should override this to return
301 /// meaningful span information. The default implementation returns `None`.
302 fn current_span(&self) -> Option<Span> {
303 None
304 }
305
306 /// Returns the format namespace for format-specific proxy resolution.
307 ///
308 /// When a field or container has format-specific proxies (e.g., `#[facet(xml::proxy = XmlProxy)]`),
309 /// this namespace is used to look up the appropriate proxy. If no namespace is returned,
310 /// only the format-agnostic proxy (`#[facet(proxy = ...)]`) is considered.
311 ///
312 /// Examples:
313 /// - XML parser should return `Some("xml")`
314 /// - JSON parser should return `Some("json")`
315 ///
316 /// Default: returns `None` (only format-agnostic proxies are used).
317 fn format_namespace(&self) -> Option<&'static str> {
318 None
319 }
320}
321
322/// Metadata about an enum variant for use with `hint_enum`.
323///
324/// Provides the information needed by non-self-describing formats to correctly
325/// parse enum variants, including the variant's structure kind and field count.
326#[derive(Debug, Clone, Copy, PartialEq, Eq)]
327#[non_exhaustive]
328pub struct EnumVariantHint {
329 /// Name of the variant (e.g., "Some", "Pair", "Named")
330 pub name: &'static str,
331 /// The kind of struct this variant represents (Unit, Tuple, TupleStruct, or Struct)
332 pub kind: facet_core::StructKind,
333 /// Number of fields in this variant
334 pub field_count: usize,
335}
336
337/// Hint for what scalar type is expected next.
338///
339/// Used by non-self-describing formats to know how to decode the next value.
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
341#[non_exhaustive]
342pub enum ScalarTypeHint {
343 /// Boolean (postcard: 0 or 1 byte)
344 Bool,
345 /// Unsigned 8-bit integer (postcard: raw byte)
346 U8,
347 /// Unsigned 16-bit integer (postcard: varint)
348 U16,
349 /// Unsigned 32-bit integer (postcard: varint)
350 U32,
351 /// Unsigned 64-bit integer (postcard: varint)
352 U64,
353 /// Unsigned 128-bit integer (postcard: varint)
354 U128,
355 /// Platform-sized unsigned integer (postcard: varint)
356 Usize,
357 /// Signed 8-bit integer (postcard: zigzag varint)
358 I8,
359 /// Signed 16-bit integer (postcard: zigzag varint)
360 I16,
361 /// Signed 32-bit integer (postcard: zigzag varint)
362 I32,
363 /// Signed 64-bit integer (postcard: zigzag varint)
364 I64,
365 /// Signed 128-bit integer (postcard: zigzag varint)
366 I128,
367 /// Platform-sized signed integer (postcard: zigzag varint)
368 Isize,
369 /// 32-bit float (postcard: 4 bytes little-endian)
370 F32,
371 /// 64-bit float (postcard: 8 bytes little-endian)
372 F64,
373 /// UTF-8 string (postcard: varint length + bytes)
374 String,
375 /// Raw bytes (postcard: varint length + bytes)
376 Bytes,
377 /// Character (postcard: UTF-8 encoded)
378 Char,
379}