Skip to main content

knowledge_base_extension_framework/
error.rs

1use crate::contracts::{BindingKey, BindingKind, BindingReference, ContractVersion, ExtensionId};
2use std::fmt;
3
4/// An error returned when a canonical extension identifier or binding key is invalid.
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct IdentifierError {
7    value: String,
8    expected: &'static str,
9}
10
11impl IdentifierError {
12    pub(crate) fn new(value: &str, expected: &'static str) -> Self {
13        Self {
14            value: value.to_owned(),
15            expected,
16        }
17    }
18}
19
20impl fmt::Display for IdentifierError {
21    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22        write!(formatter, "invalid identifier {:?}; expected {}", self.value, self.expected)
23    }
24}
25
26impl std::error::Error for IdentifierError {}
27
28/// Errors returned while registering, activating, or resolving extensions.
29#[derive(Clone, Debug, Eq, PartialEq)]
30pub enum FrameworkError {
31    DuplicateExtension(ExtensionId),
32    DuplicateDependency {
33        extension: ExtensionId,
34        dependency: ExtensionId,
35    },
36    DuplicateBinding {
37        extension: ExtensionId,
38        key: BindingKey,
39    },
40    MissingDependency {
41        extension: ExtensionId,
42        dependency: ExtensionId,
43    },
44    UnsupportedContract {
45        extension: ExtensionId,
46        required: ContractVersion,
47        available: ContractVersion,
48    },
49    DependencyCycle(Vec<ExtensionId>),
50    InactiveDependency {
51        extension: ExtensionId,
52        dependency: ExtensionId,
53    },
54    InvalidRequirement {
55        extension: ExtensionId,
56        binding: BindingReference,
57        expected: BindingKind,
58    },
59    UndeclaredBinding {
60        extension: ExtensionId,
61        binding: BindingReference,
62    },
63    InaccessibleBinding {
64        extension: ExtensionId,
65        binding: BindingReference,
66    },
67    MissingBinding(BindingReference),
68    BindingKindMismatch {
69        binding: BindingReference,
70        expected: BindingKind,
71        actual: BindingKind,
72    },
73}
74
75impl fmt::Display for FrameworkError {
76    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match self {
78            Self::DuplicateExtension(id) => write!(formatter, "extension {id} is registered more than once"),
79            Self::DuplicateDependency { extension, dependency } => write!(formatter, "extension {extension} declares dependency {dependency} more than once"),
80            Self::DuplicateBinding { extension, key } => write!(formatter, "extension {extension} declares binding {key} more than once"),
81            Self::MissingDependency { extension, dependency } => write!(formatter, "extension {extension} requires unavailable dependency {dependency}"),
82            Self::UnsupportedContract { extension, required, available } => write!(formatter, "extension {extension} requires contract {required}, but {available} is available"),
83            Self::DependencyCycle(ids) => write!(
84                formatter,
85                "extension dependency cycle: {}",
86                ids.iter().map(ToString::to_string).collect::<Vec<_>>().join(" -> ")
87            ),
88            Self::InactiveDependency { extension, dependency } => write!(formatter, "active extension {extension} requires inactive dependency {dependency}"),
89            Self::InvalidRequirement { extension, binding, expected } => write!(formatter, "extension {extension} requirement {binding} must reference a {expected:?} binding"),
90            Self::UndeclaredBinding { extension, binding } => write!(formatter, "extension {extension} does not declare binding {binding}"),
91            Self::InaccessibleBinding { extension, binding } => write!(formatter, "extension {extension} may not consume binding {binding}"),
92            Self::MissingBinding(binding) => write!(formatter, "missing binding {binding}"),
93            Self::BindingKindMismatch { binding, expected, actual } => write!(formatter, "binding {binding} has kind {actual:?}; expected {expected:?}"),
94        }
95    }
96}
97
98impl std::error::Error for FrameworkError {}