1extern crate alloc;
2
3use alloc::borrow::Cow;
4use alloc::sync::Arc;
5use core::fmt;
6use facet_core::Shape;
7
8use facet_solver::{KeyResult, Resolution, ResolutionHandle, Schema, Solver};
9
10use crate::{FormatParser, ParseError, ParseEventKind};
11
12pub struct SolveOutcome {
14 pub schema: Arc<Schema>,
16 pub resolution_index: usize,
18}
19
20#[derive(Debug)]
22#[non_exhaustive]
23pub enum SolveVariantError {
24 NoMatch,
26 Parser(ParseError),
28 SchemaError(facet_solver::SchemaError),
30}
31
32impl SolveVariantError {
33 pub const fn from_parser(e: ParseError) -> Self {
35 Self::Parser(e)
36 }
37}
38
39impl fmt::Display for SolveVariantError {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 match self {
42 Self::NoMatch => write!(f, "No variant matched"),
43 Self::Parser(e) => write!(f, "Parser error: {}", e),
44 Self::SchemaError(e) => write!(f, "Schema error: {}", e),
45 }
46 }
47}
48
49impl core::error::Error for SolveVariantError {}
50
51pub fn solve_variant<'de>(
60 shape: &'static Shape,
61 parser: &mut dyn FormatParser<'de>,
62) -> Result<Option<SolveOutcome>, SolveVariantError> {
63 let schema = Arc::new(Schema::build_auto(shape)?);
64 let mut solver = Solver::new(&schema);
65
66 let save_point = parser.save();
68
69 let mut depth = 0i32;
70 let mut in_struct = false;
71 let mut expecting_value = false;
72
73 let result = loop {
74 let event = parser
75 .next_event()
76 .map_err(SolveVariantError::from_parser)?;
77
78 let Some(event) = event else {
79 return Ok(None);
81 };
82
83 match event.kind {
84 ParseEventKind::StructStart(_) => {
85 depth += 1;
86 if depth == 1 {
87 in_struct = true;
88 }
89 }
90 ParseEventKind::StructEnd => {
91 depth -= 1;
92 if depth == 0 {
93 break None;
95 }
96 }
97 ParseEventKind::SequenceStart(_) => {
98 depth += 1;
99 }
100 ParseEventKind::SequenceEnd => {
101 depth -= 1;
102 }
103 ParseEventKind::FieldKey(key) => {
104 if depth == 1 && in_struct {
105 if let Some(name) = key.name().cloned()
107 && let Some(handle) = handle_key(&mut solver, name)
108 {
109 break Some(handle);
110 }
111 expecting_value = true;
112 }
113 }
114 ParseEventKind::Scalar(_)
115 | ParseEventKind::OrderedField
116 | ParseEventKind::VariantTag(_) => {
117 if expecting_value {
118 expecting_value = false;
119 }
120 }
121 }
122 };
123
124 parser.restore(save_point);
126
127 match result {
128 Some(handle) => {
129 let idx = handle.index();
130 Ok(Some(SolveOutcome {
131 schema,
132 resolution_index: idx,
133 }))
134 }
135 None => Ok(None),
136 }
137}
138
139fn handle_key<'a>(solver: &mut Solver<'a>, name: Cow<'a, str>) -> Option<ResolutionHandle<'a>> {
140 match solver.see_key(name) {
141 KeyResult::Solved(handle) => Some(handle),
142 KeyResult::Unknown | KeyResult::Unambiguous { .. } | KeyResult::Ambiguous { .. } => None,
143 _ => None,
145 }
146}
147
148impl From<facet_solver::SchemaError> for SolveVariantError {
149 fn from(e: facet_solver::SchemaError) -> Self {
150 Self::SchemaError(e)
151 }
152}
153
154impl SolveOutcome {
155 pub fn resolution(&self) -> &Resolution {
157 &self.schema.resolutions()[self.resolution_index]
158 }
159}