1use crate::{
2 ProfileSelection, SettingDomain, SettingId, SettingScope, SettingValue, SettingValueKind,
3};
4use animsmith_core::SourceFormatV1;
5use animsmith_core::engine_contract::EngineContractError;
6use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub enum SettingLocation {
11 Document,
13 ClipSelector(String),
15}
16
17impl fmt::Display for SettingLocation {
18 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
19 match self {
20 Self::Document => formatter.write_str("document settings"),
21 Self::ClipSelector(selector) => write!(formatter, "clip selector {selector:?}"),
22 }
23 }
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum InvalidSettingReason {
29 WrongDomain {
31 expected: SettingDomain,
33 found: SettingValueKind,
35 },
36 EmptyPath,
38 PathTooLong {
40 bytes: usize,
42 limit: usize,
44 },
45 AbsolutePath,
47 EmptyPathSegment,
49 DotPathSegment,
51 ControlCharacter,
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
57#[non_exhaustive]
58pub enum ResolutionError {
59 #[error("engine settings were declared without an engine profile selection")]
61 SettingsWithoutSelection,
62 #[error("unknown engine profile selection {0:?}")]
64 UnknownProfile(ProfileSelection),
65 #[error("unknown engine setting {key:?} in {location}")]
67 UnknownSetting {
68 key: String,
70 location: SettingLocation,
72 },
73 #[error("engine setting {setting} has {expected:?} scope but was declared in {found:?} scope")]
75 WrongScope {
76 setting: SettingId,
78 expected: SettingScope,
80 found: SettingScope,
82 location: SettingLocation,
84 },
85 #[error("engine setting {setting} is not applicable in {location}")]
87 NotApplicable {
88 setting: SettingId,
90 location: SettingLocation,
92 },
93 #[error("invalid value for engine setting {setting} in {location}: {reason:?}")]
95 InvalidSettingValue {
96 setting: SettingId,
98 location: SettingLocation,
100 reason: InvalidSettingReason,
102 },
103 #[error("missing required engine setting {setting} in {location}")]
105 MissingRequiredSetting {
106 setting: SettingId,
108 location: SettingLocation,
110 },
111 #[error("input format {format:?} is not accepted by engine profile {selection:?}")]
113 UnacceptedInputFormat {
114 selection: ProfileSelection,
116 format: SourceFormatV1,
118 },
119 #[error("resolved engine settings are outside the V1 contract: {0}")]
122 ResolvedSettingsContract(#[from] EngineContractError),
123}
124
125#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
127#[non_exhaustive]
128pub enum PredictionRuleError {
129 #[error("prediction provenance does not describe the supplied same-load source")]
132 SourceProvenanceMismatch,
133 #[error("prediction provenance does not match the frozen engine profile facts")]
136 FrozenProfileMismatch,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
141#[non_exhaustive]
142pub enum RegistryValidationError {
143 #[error("V1 registry contains {found} profiles rather than five")]
145 ProfileCount {
146 found: usize,
148 },
149 #[error("duplicate profile selection {selection:?}")]
151 DuplicateSelection {
152 selection: ProfileSelection,
154 },
155 #[error("duplicate fact-bundle URN {urn}")]
157 DuplicateFactBundleUrn {
158 urn: &'static str,
160 },
161 #[error("invalid fact inventory for {selection:?}")]
163 InvalidFactInventory {
164 selection: ProfileSelection,
166 },
167 #[error("invalid accepted-input fact for {selection:?}")]
169 InvalidAcceptedInputFact {
170 selection: ProfileSelection,
172 },
173 #[error("duplicate setting descriptor for {selection:?}")]
175 DuplicateSettingDescriptor {
176 selection: ProfileSelection,
178 },
179 #[error("invalid default status for {setting:?} in {selection:?}")]
181 InvalidDescriptorDefault {
182 selection: ProfileSelection,
184 setting: SettingId,
186 },
187 #[error("duplicate source id {source_id} in {selection:?}")]
189 DuplicateSourceId {
190 selection: ProfileSelection,
192 source_id: &'static str,
194 },
195 #[error("source {source_id} references unknown fact {fact:?} in {selection:?}")]
197 UnknownSourceFact {
198 selection: ProfileSelection,
200 source_id: &'static str,
202 fact: crate::FactId,
204 },
205 #[error("source {source_id} references non-known fact {fact:?} in {selection:?}")]
207 SourceReferencesNonKnownFact {
208 selection: ProfileSelection,
210 source_id: &'static str,
212 fact: crate::FactId,
214 },
215 #[error("source {source_id} references unknown setting {setting:?} in {selection:?}")]
217 UnknownSourceSetting {
218 selection: ProfileSelection,
220 source_id: &'static str,
222 setting: SettingId,
224 },
225 #[error("known fact {fact:?} has no source reference in {selection:?}")]
227 UnreferencedKnownFact {
228 selection: ProfileSelection,
230 fact: crate::FactId,
232 },
233 #[error("setting descriptor {setting:?} has no source reference in {selection:?}")]
235 UnreferencedSetting {
236 selection: ProfileSelection,
238 setting: SettingId,
240 },
241 #[error("facts identity mismatch for {selection:?}")]
243 FactsIdentityMismatch {
244 selection: ProfileSelection,
246 },
247}
248
249impl SettingValue {
250 pub(crate) const fn kind(&self) -> SettingValueKind {
251 match self {
252 SettingValue::Boolean(_) => SettingValueKind::Boolean,
253 SettingValue::BakeOrExtract(_) => SettingValueKind::BakeOrExtract,
254 SettingValue::SourceTransformPath(_) => SettingValueKind::SourceTransformPath,
255 }
256 }
257}