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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
use crate::{
ProfileSelection, SettingDomain, SettingId, SettingScope, SettingValue, SettingValueKind,
};
use animsmith_core::SourceFormatV1;
use animsmith_core::engine_contract::EngineContractError;
use std::fmt;
/// Location of one settings declaration.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum SettingLocation {
/// Document-wide engine settings.
Document,
/// Settings declared under one clip selector.
ClipSelector(String),
}
impl fmt::Display for SettingLocation {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Document => formatter.write_str("document settings"),
Self::ClipSelector(selector) => write!(formatter, "clip selector {selector:?}"),
}
}
}
/// Why a closed setting value failed its declared domain.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum InvalidSettingReason {
/// The value variant does not match the descriptor domain.
WrongDomain {
/// Required descriptor domain.
expected: SettingDomain,
/// Supplied closed value kind.
found: SettingValueKind,
},
/// The transform path is empty.
EmptyPath,
/// The transform path exceeds the V1 UTF-8 byte limit.
PathTooLong {
/// Actual UTF-8 byte count.
bytes: usize,
/// Maximum UTF-8 byte count.
limit: usize,
},
/// The transform path begins with `/` and is not relative.
AbsolutePath,
/// The transform path contains an empty segment.
EmptyPathSegment,
/// The transform path contains `.` or `..`.
DotPathSegment,
/// The transform path contains an ASCII control character.
ControlCharacter,
}
/// Typed failure from static or input-dependent engine resolution.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum ResolutionError {
/// Settings were declared without selecting an engine profile.
#[error("engine settings were declared without an engine profile selection")]
SettingsWithoutSelection,
/// No exact registry tuple matches the selection.
#[error("unknown engine profile selection {0:?}")]
UnknownProfile(ProfileSelection),
/// A setting key is not in the selected profile's descriptor inventory.
#[error("unknown engine setting {key:?} in {location}")]
UnknownSetting {
/// Supplied setting key.
key: String,
/// Declaration location.
location: SettingLocation,
},
/// A known setting was declared in the wrong scope.
#[error("engine setting {setting} has {expected:?} scope but was declared in {found:?} scope")]
WrongScope {
/// Stable setting id.
setting: SettingId,
/// Descriptor scope.
expected: SettingScope,
/// Supplied scope.
found: SettingScope,
/// Declaration location.
location: SettingLocation,
},
/// A known descriptor genuinely does not apply to the selected profile.
#[error("engine setting {setting} is not applicable in {location}")]
NotApplicable {
/// Stable setting id.
setting: SettingId,
/// Declaration location.
location: SettingLocation,
},
/// A setting value is outside its closed descriptor domain.
#[error("invalid value for engine setting {setting} in {location}: {reason:?}")]
InvalidSettingValue {
/// Stable setting id.
setting: SettingId,
/// Declaration location.
location: SettingLocation,
/// Exact domain/path failure.
reason: InvalidSettingReason,
},
/// One required-without-default setting was not materialized.
#[error("missing required engine setting {setting} in {location}")]
MissingRequiredSetting {
/// Stable setting id.
setting: SettingId,
/// Document or exact real clip requiring the setting.
location: SettingLocation,
},
/// The authoritative input container is outside the selected V1 boundary.
#[error("input format {format:?} is not accepted by engine profile {selection:?}")]
UnacceptedInputFormat {
/// Selected exact profile tuple.
selection: ProfileSelection,
/// Authoritative loader-owned input format.
format: SourceFormatV1,
},
/// Fully materialized settings exceeded or contradicted the bounded V1
/// engine contract.
#[error("resolved engine settings are outside the V1 contract: {0}")]
ResolvedSettingsContract(#[from] EngineContractError),
}
/// Typed failure while binding an engine-owned check to immutable evidence.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum PredictionRuleError {
/// The supplied provenance was not projected from the supplied same-load
/// source facts and dependency closure.
#[error("prediction provenance does not describe the supplied same-load source")]
SourceProvenanceMismatch,
/// An exact built-in profile tuple carried facts other than the immutable
/// registry record for that revision.
#[error("prediction provenance does not match the frozen engine profile facts")]
FrozenProfileMismatch,
}
/// Author-owned invariant failure in the built-in V1 registry.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum RegistryValidationError {
/// V1 did not contain exactly five singleton profiles.
#[error("V1 registry contains {found} profiles rather than five")]
ProfileCount {
/// Actual profile count.
found: usize,
},
/// Two records use the same exact selection.
#[error("duplicate profile selection {selection:?}")]
DuplicateSelection {
/// Repeated selection.
selection: ProfileSelection,
},
/// Two records use the same revisioned fact-bundle URN.
#[error("duplicate fact-bundle URN {urn}")]
DuplicateFactBundleUrn {
/// Repeated URN.
urn: &'static str,
},
/// The record does not enumerate every stable V1 fact id exactly once.
#[error("invalid fact inventory for {selection:?}")]
InvalidFactInventory {
/// Affected selection.
selection: ProfileSelection,
},
/// The accepted-input fact is not a nonempty canonical known-format set.
#[error("invalid accepted-input fact for {selection:?}")]
InvalidAcceptedInputFact {
/// Affected selection.
selection: ProfileSelection,
},
/// A setting descriptor id is repeated.
#[error("duplicate setting descriptor for {selection:?}")]
DuplicateSettingDescriptor {
/// Affected selection.
selection: ProfileSelection,
},
/// Applicability and default status contradict each other.
#[error("invalid default status for {setting:?} in {selection:?}")]
InvalidDescriptorDefault {
/// Affected selection.
selection: ProfileSelection,
/// Affected setting.
setting: SettingId,
},
/// A primary-source id is repeated within one profile.
#[error("duplicate source id {source_id} in {selection:?}")]
DuplicateSourceId {
/// Affected selection.
selection: ProfileSelection,
/// Repeated source id.
source_id: &'static str,
},
/// A source references a fact outside the record vocabulary.
#[error("source {source_id} references unknown fact {fact:?} in {selection:?}")]
UnknownSourceFact {
/// Affected selection.
selection: ProfileSelection,
/// Source id.
source_id: &'static str,
/// Unknown fact id.
fact: crate::FactId,
},
/// A source claims support for a fact whose record state is not known.
#[error("source {source_id} references non-known fact {fact:?} in {selection:?}")]
SourceReferencesNonKnownFact {
/// Affected selection.
selection: ProfileSelection,
/// Source id.
source_id: &'static str,
/// Fact without a known value.
fact: crate::FactId,
},
/// A source references a setting absent from the record.
#[error("source {source_id} references unknown setting {setting:?} in {selection:?}")]
UnknownSourceSetting {
/// Affected selection.
selection: ProfileSelection,
/// Source id.
source_id: &'static str,
/// Missing setting id.
setting: SettingId,
},
/// A known fact has no supporting primary-source reference.
#[error("known fact {fact:?} has no source reference in {selection:?}")]
UnreferencedKnownFact {
/// Affected selection.
selection: ProfileSelection,
/// Unsupported known fact.
fact: crate::FactId,
},
/// A descriptor has no supporting primary-source reference.
#[error("setting descriptor {setting:?} has no source reference in {selection:?}")]
UnreferencedSetting {
/// Affected selection.
selection: ProfileSelection,
/// Unsupported descriptor.
setting: SettingId,
},
/// The stored record identity differs from a fresh canonical encoding.
#[error("facts identity mismatch for {selection:?}")]
FactsIdentityMismatch {
/// Affected selection.
selection: ProfileSelection,
},
}
impl SettingValue {
pub(crate) const fn kind(&self) -> SettingValueKind {
match self {
SettingValue::Boolean(_) => SettingValueKind::Boolean,
SettingValue::BakeOrExtract(_) => SettingValueKind::BakeOrExtract,
SettingValue::SourceTransformPath(_) => SettingValueKind::SourceTransformPath,
}
}
}