facet_format/
parser.rs

1use crate::FieldEvidence;
2
3/// Streaming cursor that yields serialized fields for solver probing.
4pub trait ProbeStream<'de> {
5    /// Parser-specific error type.
6    type Error;
7
8    /// Produce the next field evidence entry. Returning `Ok(None)` indicates
9    /// the parser ran out of evidence or the format does not need additional
10    /// passes.
11    fn next(&mut self) -> Result<Option<FieldEvidence<'de>>, Self::Error>;
12}
13
14/// Streaming parser for a specific wire format.
15pub trait FormatParser<'de> {
16    /// Parser-specific error type.
17    type Error;
18
19    /// Evidence cursor type produced by [`FormatParser::begin_probe`].
20    type Probe<'a>: ProbeStream<'de, Error = Self::Error>
21    where
22        Self: 'a;
23
24    /// Read the next parse event.
25    fn next_event(&mut self) -> Result<crate::ParseEvent<'de>, Self::Error>;
26
27    /// Peek at the next event without consuming it.
28    fn peek_event(&mut self) -> Result<crate::ParseEvent<'de>, Self::Error>;
29
30    /// Skip the current value (for unknown fields, etc.).
31    fn skip_value(&mut self) -> Result<(), Self::Error>;
32
33    /// Begin evidence collection for untagged-enum resolution.
34    fn begin_probe(&mut self) -> Result<Self::Probe<'_>, Self::Error>;
35
36    /// Capture the raw representation of the current value without parsing it.
37    ///
38    /// This is used for types like `RawJson` that want to defer parsing.
39    /// The parser should skip the value and return the raw bytes/string
40    /// from the input.
41    ///
42    /// Returns `Ok(None)` if raw capture is not supported (e.g., streaming mode
43    /// or formats where raw capture doesn't make sense).
44    fn capture_raw(&mut self) -> Result<Option<&'de str>, Self::Error> {
45        // Default: not supported
46        self.skip_value()?;
47        Ok(None)
48    }
49
50    /// Returns the shape of the format's raw capture type (e.g., `RawJson::SHAPE`).
51    ///
52    /// When the deserializer encounters a shape that matches this, it will use
53    /// `capture_raw` to capture the raw representation and store it in a
54    /// `Cow<str>` (the raw type must be a newtype over `Cow<str>`).
55    ///
56    /// Returns `None` if this format doesn't support raw capture types.
57    fn raw_capture_shape(&self) -> Option<&'static facet_core::Shape> {
58        None
59    }
60}
61
62/// Extension trait for parsers that support format-specific JIT (Tier 2).
63///
64/// Parsers implement this trait to enable the Tier 2 fast path, which
65/// generates Cranelift IR that parses bytes directly instead of going
66/// through the event abstraction.
67///
68/// # Requirements
69///
70/// Tier 2 requires:
71/// - The full input slice must be available upfront
72/// - The parser must be able to report and update its cursor position
73/// - The parser must reset internal state when `jit_set_pos` is called
74#[cfg(feature = "jit")]
75pub trait FormatJitParser<'de>: FormatParser<'de> {
76    /// The format-specific JIT emitter type.
77    type FormatJit: crate::jit::JitFormat;
78
79    /// Return the full input slice.
80    fn jit_input(&self) -> &'de [u8];
81
82    /// Return the current byte offset (cursor position).
83    ///
84    /// Returns `None` if there is buffered state (e.g., a peeked event)
85    /// that makes the position ambiguous.
86    fn jit_pos(&self) -> Option<usize>;
87
88    /// Commit a new cursor position after Tier 2 execution succeeds.
89    ///
90    /// Must also invalidate/reset any internal scanning/tokenizer state
91    /// so that subsequent parsing continues from `pos` consistently.
92    fn jit_set_pos(&mut self, pos: usize);
93
94    /// Return a format JIT emitter instance (usually a ZST).
95    fn jit_format(&self) -> Self::FormatJit;
96
97    /// Convert a Tier 2 error (code + position) into `Self::Error`.
98    fn jit_error(&self, input: &'de [u8], error_pos: usize, error_code: i32) -> Self::Error;
99}