1use std::fmt;
4
5#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum InstError {
9 #[error("node not found: {0}")]
11 NodeNotFound(u32),
12
13 #[error("vertex not found in schema: {0}")]
15 VertexNotFound(String),
16
17 #[error("root node missing from instance")]
19 MissingRoot,
20
21 #[error("dangling arc: ({src}, {tgt})")]
23 DanglingArc {
24 src: u32,
26 tgt: u32,
28 },
29
30 #[error("eval_hom failed: {0}")]
32 EvalHom(String),
33}
34
35#[derive(Debug, thiserror::Error)]
37#[non_exhaustive]
38pub enum RestrictError {
39 #[error("no edge found between {src} and {tgt} in target schema")]
41 NoEdgeFound {
42 src: String,
44 tgt: String,
46 },
47
48 #[error("ambiguous edge between {src} and {tgt}: {count} candidates")]
50 AmbiguousEdge {
51 src: String,
53 tgt: String,
55 count: usize,
57 },
58
59 #[error("root node was pruned during restriction")]
61 RootPruned,
62
63 #[error("fan reconstruction failed for hyper-edge {hyper_edge_id}: {detail}")]
65 FanReconstructionFailed {
66 hyper_edge_id: String,
68 detail: String,
70 },
71
72 #[error("product size {actual} exceeds limit {limit} for vertex {vertex}")]
74 ProductSizeExceeded {
75 vertex: String,
77 actual: usize,
79 limit: usize,
81 },
82
83 #[error("multi-element fiber for vertex {vertex}: {count} source vertices")]
86 MultiElementFiber {
87 vertex: String,
89 count: usize,
91 },
92}
93
94#[derive(Debug, thiserror::Error)]
96#[non_exhaustive]
97pub enum ParseError {
98 #[error("root vertex not found in schema: {0}")]
100 RootVertexNotFound(String),
101
102 #[error("expected JSON object at path {path}")]
104 ExpectedObject {
105 path: String,
107 },
108
109 #[error("expected JSON array at path {path}")]
111 ExpectedArray {
112 path: String,
114 },
115
116 #[error("unknown edge target at path {path}: {detail}")]
118 UnknownEdgeTarget {
119 path: String,
121 detail: String,
123 },
124
125 #[error("invalid value at path {path}: {detail}")]
127 InvalidValue {
128 path: String,
130 detail: String,
132 },
133
134 #[error("JSON error: {0}")]
136 Json(#[from] serde_json::Error),
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
141#[non_exhaustive]
142pub enum ValidationError {
143 InvalidAnchor {
145 node_id: u32,
147 anchor: String,
149 },
150
151 InvalidEdge {
153 parent: u32,
155 child: u32,
157 detail: String,
159 },
160
161 MissingRoot,
163
164 UnreachableNode {
166 node_id: u32,
168 },
169
170 MissingRequiredEdge {
172 node_id: u32,
174 edge: String,
176 },
177
178 ParentMapInconsistent {
180 node_id: u32,
182 detail: String,
184 },
185
186 InvalidFan {
188 hyper_edge_id: String,
190 detail: String,
192 },
193}
194
195impl fmt::Display for ValidationError {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 match self {
198 Self::InvalidAnchor { node_id, anchor } => {
199 write!(f, "node {node_id} has invalid anchor: {anchor}")
200 }
201 Self::InvalidEdge {
202 parent,
203 child,
204 detail,
205 } => write!(f, "invalid edge ({parent}, {child}): {detail}"),
206 Self::MissingRoot => write!(f, "root node is missing"),
207 Self::UnreachableNode { node_id } => {
208 write!(f, "node {node_id} is unreachable from root")
209 }
210 Self::MissingRequiredEdge { node_id, edge } => {
211 write!(f, "node {node_id} missing required edge: {edge}")
212 }
213 Self::ParentMapInconsistent { node_id, detail } => {
214 write!(f, "parent map inconsistency at node {node_id}: {detail}")
215 }
216 Self::InvalidFan {
217 hyper_edge_id,
218 detail,
219 } => write!(f, "invalid fan for hyper-edge {hyper_edge_id}: {detail}"),
220 }
221 }
222}