panproto_schema/error.rs
1//! Error types for schema operations.
2
3use std::fmt;
4
5/// Errors that can occur during schema construction and validation.
6#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum SchemaError {
9 /// A vertex ID was referenced but not found in the schema.
10 #[error("vertex not found: {0}")]
11 VertexNotFound(String),
12
13 /// A duplicate vertex ID was added to the schema.
14 #[error("duplicate vertex id: {0}")]
15 DuplicateVertex(String),
16
17 /// A duplicate edge was added to the schema.
18 #[error("duplicate edge from {src} to {tgt} of kind {kind}")]
19 DuplicateEdge {
20 /// Source vertex ID.
21 src: String,
22 /// Target vertex ID.
23 tgt: String,
24 /// Edge kind.
25 kind: String,
26 },
27
28 /// A duplicate hyper-edge ID was added to the schema.
29 #[error("duplicate hyper-edge id: {0}")]
30 DuplicateHyperEdge(String),
31
32 /// An edge kind violates the protocol's edge rules.
33 #[error(
34 "invalid edge kind {kind}: source kind {src_kind} not allowed (permitted: {permitted})"
35 )]
36 InvalidEdgeSource {
37 /// The edge kind.
38 kind: String,
39 /// The actual source vertex kind.
40 src_kind: String,
41 /// Comma-separated list of permitted source kinds.
42 permitted: String,
43 },
44
45 /// An edge kind violates the protocol's edge rules (target).
46 #[error(
47 "invalid edge kind {kind}: target kind {tgt_kind} not allowed (permitted: {permitted})"
48 )]
49 InvalidEdgeTarget {
50 /// The edge kind.
51 kind: String,
52 /// The actual target vertex kind.
53 tgt_kind: String,
54 /// Comma-separated list of permitted target kinds.
55 permitted: String,
56 },
57
58 /// An edge kind is not recognized by the protocol.
59 #[error("unknown edge kind: {0}")]
60 UnknownEdgeKind(String),
61
62 /// A vertex kind is not recognized by the protocol's schema theory.
63 #[error("unknown vertex kind: {0}")]
64 UnknownVertexKind(String),
65
66 /// The schema has no vertices.
67 #[error("schema has no vertices")]
68 EmptySchema,
69
70 /// A declared entry vertex does not exist in the schema.
71 #[error("entry vertex not found: {0}")]
72 UnknownEntryVertex(String),
73
74 /// `SchemaBuilder::build_abstract` was called on a builder that
75 /// has accumulated constraints in the layout enrichment fibre.
76 /// Abstract schemas must carry no layout witnesses; call
77 /// `build_decorated` if a decorated schema was intended.
78 #[error(
79 "build_abstract called on a builder with layout-fibre constraints; \
80 use build_decorated for a decorated schema"
81 )]
82 LayoutConstraintsOnAbstractBuild,
83}
84
85/// An error found during schema validation against a protocol.
86#[derive(Debug, Clone, PartialEq, Eq)]
87#[non_exhaustive]
88pub enum ValidationError {
89 /// An edge violates the protocol's edge rules.
90 InvalidEdge {
91 /// The offending edge's source vertex ID.
92 src: String,
93 /// The offending edge's target vertex ID.
94 tgt: String,
95 /// The edge kind.
96 kind: String,
97 /// Human-readable reason for the violation.
98 reason: String,
99 },
100
101 /// A constraint uses a sort not recognized by the protocol.
102 InvalidConstraintSort {
103 /// The vertex with the invalid constraint.
104 vertex: String,
105 /// The unrecognized sort.
106 sort: String,
107 },
108
109 /// A vertex kind is not recognized by the protocol.
110 InvalidVertexKind {
111 /// The vertex ID.
112 vertex: String,
113 /// The unrecognized kind.
114 kind: String,
115 },
116
117 /// A required edge references a missing vertex.
118 DanglingRequiredEdge {
119 /// The vertex ID.
120 vertex: String,
121 /// The dangling edge description.
122 edge: String,
123 },
124}
125
126impl fmt::Display for ValidationError {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 match self {
129 Self::InvalidEdge {
130 src,
131 tgt,
132 kind,
133 reason,
134 } => write!(f, "invalid edge {src} -> {tgt} ({kind}): {reason}"),
135 Self::InvalidConstraintSort { vertex, sort } => {
136 write!(f, "vertex {vertex} has invalid constraint sort: {sort}")
137 }
138 Self::InvalidVertexKind { vertex, kind } => {
139 write!(f, "vertex {vertex} has invalid kind: {kind}")
140 }
141 Self::DanglingRequiredEdge { vertex, edge } => {
142 write!(f, "vertex {vertex} has dangling required edge: {edge}")
143 }
144 }
145 }
146}