Skip to main content

encounter_argumentation/
error.rs

1//! Error types for encounter-argumentation bridge operations.
2
3use thiserror::Error;
4
5/// Errors that can occur during argumentation bridge operations.
6#[derive(Debug, Error)]
7pub enum Error {
8    /// A requested scheme key was not found in the registry.
9    #[error("scheme not found: {0}")]
10    SchemeNotFound(String),
11
12    /// A required slot binding was missing when instantiating a scheme.
13    #[error("missing binding for scheme {scheme}: slot {slot}")]
14    MissingBinding {
15        /// The name of the scheme that required the binding.
16        scheme: String,
17        /// The slot that was not bound.
18        slot: String,
19    },
20
21    /// An error propagated from the argumentation-schemes layer.
22    #[error("scheme error: {0}")]
23    Scheme(#[from] argumentation_schemes::Error),
24
25    /// An error propagated directly from the core Dung/ASPIC+ layer.
26    #[error("core argumentation error: {0}")]
27    Dung(#[from] argumentation::Error),
28
29    /// An error propagated from the argumentation-bipolar layer.
30    #[error("bipolar error: {0}")]
31    Bipolar(#[from] argumentation_bipolar::Error),
32
33    /// An error propagated from the argumentation-weighted layer.
34    #[error("weighted error: {0}")]
35    Weighted(#[from] argumentation_weighted::Error),
36
37    /// An error propagated from the argumentation-weighted-bipolar layer.
38    #[error("weighted-bipolar error: {0}")]
39    WeightedBipolar(#[from] argumentation_weighted_bipolar::Error),
40
41    /// An affordance passed to `StateAcceptanceEval` has no `"self"`
42    /// binding, so the bridge cannot identify the proposer. The eval
43    /// defaulted to *accept* for this action. Surfaces via
44    /// [`crate::state::EncounterArgumentationState::drain_errors`].
45    /// Consumers who use a non-`"self"` proposer slot name should wrap
46    /// `StateAcceptanceEval` with a custom implementation.
47    #[error("acceptance eval could not find a 'self' binding on affordance {affordance_name}")]
48    MissingProposerBinding {
49        /// The affordance name with no `"self"` binding.
50        affordance_name: String,
51    },
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn error_from_bipolar_propagates() {
60        let bipolar_err = argumentation_bipolar::Error::IllegalSelfSupport("x".into());
61        let err: Error = bipolar_err.into();
62        assert!(matches!(err, Error::Bipolar(_)));
63    }
64
65    #[test]
66    fn error_from_weighted_propagates() {
67        let weighted_err = argumentation_weighted::Error::InvalidWeight { weight: -1.0 };
68        let err: Error = weighted_err.into();
69        assert!(matches!(err, Error::Weighted(_)));
70    }
71
72    #[test]
73    fn error_from_wbipolar_propagates() {
74        let wbp_err = argumentation_weighted_bipolar::Error::IllegalSelfSupport;
75        let err: Error = wbp_err.into();
76        assert!(matches!(err, Error::WeightedBipolar(_)));
77    }
78
79    #[test]
80    fn error_from_dung_propagates() {
81        // TooLarge is the simplest constructible argumentation::Error variant.
82        let core_err = argumentation::Error::TooLarge { arguments: 100, limit: 22 };
83        let err: Error = core_err.into();
84        assert!(matches!(err, Error::Dung(_)));
85    }
86}