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