Skip to main content

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
75/// An error found during schema validation against a protocol.
76#[derive(Debug, Clone, PartialEq, Eq)]
77#[non_exhaustive]
78pub enum ValidationError {
79    /// An edge violates the protocol's edge rules.
80    InvalidEdge {
81        /// The offending edge's source vertex ID.
82        src: String,
83        /// The offending edge's target vertex ID.
84        tgt: String,
85        /// The edge kind.
86        kind: String,
87        /// Human-readable reason for the violation.
88        reason: String,
89    },
90
91    /// A constraint uses a sort not recognized by the protocol.
92    InvalidConstraintSort {
93        /// The vertex with the invalid constraint.
94        vertex: String,
95        /// The unrecognized sort.
96        sort: String,
97    },
98
99    /// A vertex kind is not recognized by the protocol.
100    InvalidVertexKind {
101        /// The vertex ID.
102        vertex: String,
103        /// The unrecognized kind.
104        kind: String,
105    },
106
107    /// A required edge references a missing vertex.
108    DanglingRequiredEdge {
109        /// The vertex ID.
110        vertex: String,
111        /// The dangling edge description.
112        edge: String,
113    },
114}
115
116impl fmt::Display for ValidationError {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118        match self {
119            Self::InvalidEdge {
120                src,
121                tgt,
122                kind,
123                reason,
124            } => write!(f, "invalid edge {src} -> {tgt} ({kind}): {reason}"),
125            Self::InvalidConstraintSort { vertex, sort } => {
126                write!(f, "vertex {vertex} has invalid constraint sort: {sort}")
127            }
128            Self::InvalidVertexKind { vertex, kind } => {
129                write!(f, "vertex {vertex} has invalid kind: {kind}")
130            }
131            Self::DanglingRequiredEdge { vertex, edge } => {
132                write!(f, "vertex {vertex} has dangling required edge: {edge}")
133            }
134        }
135    }
136}