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}