facet_format/
event.rs

1extern crate alloc;
2
3use alloc::borrow::Cow;
4use core::fmt;
5
6/// Location hint for a serialized field.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum FieldLocationHint {
9    /// Key/value entry (JSON/YAML/TOML).
10    KeyValue,
11    /// XML attribute.
12    Attribute,
13    /// XML/KDL text node.
14    Text,
15    /// XML/KDL child element/node.
16    Child,
17    /// KDL property.
18    Property,
19    /// KDL positional argument.
20    Argument,
21}
22
23/// Field key with optional namespace (for XML).
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct FieldKey<'de> {
26    /// Field name.
27    pub name: Cow<'de, str>,
28    /// Location hint.
29    pub location: FieldLocationHint,
30    /// Optional namespace URI (for XML namespace support).
31    pub namespace: Option<Cow<'de, str>>,
32}
33
34impl<'de> FieldKey<'de> {
35    /// Create a new field key without namespace.
36    pub fn new(name: impl Into<Cow<'de, str>>, location: FieldLocationHint) -> Self {
37        Self {
38            name: name.into(),
39            location,
40            namespace: None,
41        }
42    }
43
44    /// Add a namespace to this field key (builder pattern).
45    pub fn with_namespace(mut self, namespace: impl Into<Cow<'de, str>>) -> Self {
46        self.namespace = Some(namespace.into());
47        self
48    }
49}
50
51/// The kind of container being parsed.
52///
53/// This distinguishes between format-specific container types to enable
54/// better error messages and type checking.
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum ContainerKind {
57    /// JSON/YAML/TOML object: definitely struct-like with key-value pairs.
58    /// Type mismatches (e.g., object where array expected) should produce errors.
59    Object,
60    /// JSON/YAML array: definitely sequence-like.
61    /// Type mismatches (e.g., array where object expected) should produce errors.
62    Array,
63    /// XML/KDL element: semantically ambiguous.
64    /// Could be interpreted as struct, sequence, or scalar wrapper depending on target type.
65    /// The deserializer decides based on what type it's deserializing into.
66    Element,
67}
68
69impl ContainerKind {
70    /// Returns true if this container kind is ambiguous (can be struct or sequence).
71    pub fn is_ambiguous(self) -> bool {
72        matches!(self, ContainerKind::Element)
73    }
74
75    /// Human-readable name for error messages.
76    pub fn name(self) -> &'static str {
77        match self {
78            ContainerKind::Object => "object",
79            ContainerKind::Array => "array",
80            ContainerKind::Element => "element",
81        }
82    }
83}
84
85/// Value classification hint for evidence gathering.
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum ValueTypeHint {
88    /// Null-like values.
89    Null,
90    /// Boolean.
91    Bool,
92    /// Numeric primitive.
93    Number,
94    /// Text string.
95    String,
96    /// Raw bytes (e.g., base64 segments).
97    Bytes,
98    /// Sequence (array/list/tuple).
99    Sequence,
100    /// Map/struct/object.
101    Map,
102}
103
104/// Scalar data extracted from the wire format.
105#[derive(Debug, Clone, PartialEq)]
106pub enum ScalarValue<'de> {
107    /// Null literal.
108    Null,
109    /// Boolean literal.
110    Bool(bool),
111    /// Signed integer literal.
112    I64(i64),
113    /// Unsigned integer literal.
114    U64(u64),
115    /// Floating-point literal.
116    F64(f64),
117    /// UTF-8 string literal.
118    Str(Cow<'de, str>),
119    /// Binary literal.
120    Bytes(Cow<'de, [u8]>),
121}
122
123/// Event emitted by a format parser while streaming through input.
124#[derive(Clone, PartialEq)]
125pub enum ParseEvent<'de> {
126    /// Beginning of a struct/object/node.
127    StructStart(ContainerKind),
128    /// End of a struct/object/node.
129    StructEnd,
130    /// Encountered a field key.
131    FieldKey(FieldKey<'de>),
132    /// Beginning of a sequence/array/tuple.
133    SequenceStart(ContainerKind),
134    /// End of a sequence/array/tuple.
135    SequenceEnd,
136    /// Scalar literal.
137    Scalar(ScalarValue<'de>),
138    /// Variant discriminant that needs to be propagated to the solver.
139    VariantTag(&'de str),
140}
141
142impl<'de> fmt::Debug for ParseEvent<'de> {
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        match self {
145            ParseEvent::StructStart(kind) => f.debug_tuple("StructStart").field(kind).finish(),
146            ParseEvent::StructEnd => f.write_str("StructEnd"),
147            ParseEvent::FieldKey(key) => f.debug_tuple("FieldKey").field(key).finish(),
148            ParseEvent::SequenceStart(kind) => f.debug_tuple("SequenceStart").field(kind).finish(),
149            ParseEvent::SequenceEnd => f.write_str("SequenceEnd"),
150            ParseEvent::Scalar(value) => f.debug_tuple("Scalar").field(value).finish(),
151            ParseEvent::VariantTag(tag) => f.debug_tuple("VariantTag").field(tag).finish(),
152        }
153    }
154}