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