1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! Error types for lens operations.
//!
//! [`LensError`] covers failures during lens construction and combinator
//! compilation. [`LawViolation`] reports failures of the round-trip laws
//! (`GetPut` and `PutGet`).
use std::fmt;
/// Errors from lens construction, combinator compilation, or lens operations.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum LensError {
/// A schema vertex referenced by a combinator was not found.
#[error("vertex not found: {0}")]
VertexNotFound(String),
/// An edge referenced by a combinator was not found.
#[error("edge not found: {src} -> {tgt}")]
EdgeNotFound {
/// Source vertex.
src: String,
/// Target vertex.
tgt: String,
},
/// A combinator references an invalid field name.
#[error("field not found: {0}")]
FieldNotFound(String),
/// A combinator references an NSID on a vertex that has no NSID.
#[error("no NSID on vertex: {0}")]
NsidNotFound(String),
/// A combinator references a constraint sort that does not exist.
#[error("constraint sort not found: {0}")]
ConstraintSortNotFound(String),
/// A combinator references an edge kind that does not exist.
#[error("edge kind not found: {0}")]
EdgeKindNotFound(String),
/// Type coercion between incompatible kinds.
#[error("cannot coerce from {from} to {to}")]
IncompatibleCoercion {
/// Source kind.
from: String,
/// Target kind.
to: String,
},
/// Lens composition failed because schemas don't align.
#[error(
"composition failed: target schema of first lens does not match source schema of second"
)]
CompositionMismatch,
/// Delegation to the restrict pipeline failed.
#[error("restrict error: {0}")]
Restrict(#[from] panproto_inst::RestrictError),
/// A complement was incompatible with the view during `put`.
#[error("complement mismatch: {detail}")]
ComplementMismatch {
/// Details about the mismatch.
detail: String,
},
/// A protolens operation failed.
#[error("protolens error: {0}")]
ProtolensError(String),
/// An edit could not be applied during law checking.
#[error("edit apply error: {0}")]
EditApply(#[from] panproto_inst::EditError),
/// Partial-monoid `Complement::compose` rejected an attempted merge
/// because both operands carried distinct entries on the same key.
/// Composition is defined exactly when the two complements agree on
/// every shared key (idempotent merge); disagreement is the
/// boundary of the partial-monoid's domain of definition.
#[error("complement conflict on {kind} key `{key}`")]
ComplementConflict {
/// Which keyed map produced the conflict.
kind: &'static str,
/// String representation of the conflicting key.
key: String,
},
/// Partial-monoid `Complement::compose` rejected an attempted merge
/// because the two complements were taken at distinct source
/// schemas (their fingerprints differ).
#[error(
"complement fingerprint mismatch: {left:#x} vs {right:#x}; complements were captured against different source schemas"
)]
ComplementFingerprintMismatch {
/// Left fingerprint.
left: u64,
/// Right fingerprint.
right: u64,
},
/// No enrichment synthesis driver is registered for the named
/// `(kind, enricher)` pair. The driver must be registered via
/// [`enrichment_registry::register_enricher`](crate::enrichment_registry::register_enricher)
/// before a protolens that adds this enrichment can be
/// instantiated.
#[error("no enrichment driver registered for ({kind:?}, {enricher:?})")]
UnknownEnricher {
/// The enrichment kind requested.
kind: panproto_gat::EnrichmentKind,
/// The enricher name (e.g. a grammar name for `Layout`).
enricher: String,
},
/// The registered enrichment synthesis driver rejected its input.
#[error("enrichment synthesis failed ({kind:?}, {enricher}): {detail}")]
EnrichmentSynthesisFailed {
/// The enrichment kind.
kind: panproto_gat::EnrichmentKind,
/// The enricher name.
enricher: String,
/// Human-readable failure.
detail: String,
},
}
/// A violation of a round-trip lens law.
#[derive(Debug)]
#[non_exhaustive]
pub enum LawViolation {
/// `GetPut` law violation: `put(s, get(s)) != s`.
GetPut {
/// Human-readable description of the difference.
detail: String,
},
/// `PutGet` law violation: `get(put(s, v)) != v`.
PutGet {
/// Human-readable description of the difference.
detail: String,
},
/// An error occurred while checking the laws.
Error(LensError),
}
impl fmt::Display for LawViolation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::GetPut { detail } => write!(f, "GetPut law violated: {detail}"),
Self::PutGet { detail } => write!(f, "PutGet law violated: {detail}"),
Self::Error(e) => write!(f, "error during law check: {e}"),
}
}
}
impl std::error::Error for LawViolation {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Error(e) => Some(e),
_ => None,
}
}
}