1
use super::stored::ReprRuleStored;
2
#[allow(unused_imports)]
3
use super::types::{ReprDeclLevel, ReprDomainLevel};
4
use crate::ast::{DeclarationPtr, DomainPtr, Literal};
5
use std::fmt::Debug;
6
use thiserror::Error;
7

            
8
/// Errors that can be thrown by [ReprDomainLevel::init]
9
#[derive(Debug, Error)]
10
pub enum ReprInitError {
11
    /// The given domain isn't supported by this representation
12
    #[error("domain `{}` is not supported by representation `{}`{}", .0, .1, if .2.is_empty() { String::from("") } else { format!(": {}", .2) })]
13
    UnsupportedDomain(DomainPtr, &'static str, String),
14
    /// This representation only targets other solver families.
15
    #[error("representation `{}` is not applicable to solver family `{}`", .0, .1.as_str())]
16
    WrongSolverFamily(&'static str, crate::settings::SolverFamily),
17
    /// A different representation is already selected for this type family.
18
    #[error(
19
        "uniform representation conflict for domain `{domain}`: selected `{existing}`, requested `{requested}`"
20
    )]
21
    UniformConflict {
22
        domain: DomainPtr,
23
        existing: &'static str,
24
        requested: &'static str,
25
    },
26
    /// Can't initialise representation for a different reason
27
    #[error(transparent)]
28
    Other(#[from] anyhow::Error),
29
}
30

            
31
/// Errors that can be thrown by [ReprDomainLevel::instantiate]
32
#[derive(Debug, Error)]
33
pub enum ReprInstantiateError {
34
    /// An instance of this representation already exists for this variable
35
    #[error("representation `{}` is already initialised for `{}`", .1, .0.name())]
36
    AlreadyExists(DeclarationPtr, &'static str),
37
    /// Channelling is disabled and another representation has already been selected.
38
    #[error(
39
        "cannot initialise representation `{requested}` for `{declaration}` because it already uses `{existing}` and channelling is disabled"
40
    )]
41
    ConflictingRepresentation {
42
        declaration: DeclarationPtr,
43
        existing: &'static str,
44
        requested: &'static str,
45
    },
46
    /// The given variable had no domain
47
    #[error("declaration `{}` (`{}`) had no domain", .0.name(), .0)]
48
    NoDomain(DeclarationPtr),
49
    /// The given variable was of an unsupported kind
50
    #[error("declaration `{}` (`{}`) had an unsupported kind{}", .0.name(), .0, if .1.is_empty() { String::from("") } else { format!(": {}", .1) })]
51
    BadKind(DeclarationPtr, String),
52
    /// This variable's domain is different from the one this domain-level representation is for
53
    #[error("got `{}: {}`, but this representation is for domain `{}`", .0.name(), .0.domain().map(|d| d.to_string()).unwrap_or(String::from("None")), .1)]
54
    BadDomain(DeclarationPtr, DomainPtr),
55
    /// Can't instantiate representation for a different reason
56
    #[error(transparent)]
57
    Other(#[from] anyhow::Error),
58
}
59

            
60
/// Either [ReprInitError] or [ReprInstantiateError]
61
#[derive(Debug, Error)]
62
pub enum ReprError {
63
    #[error(transparent)]
64
    Init(#[from] ReprInitError),
65
    #[error(transparent)]
66
    Instantiate(#[from] ReprInstantiateError),
67
}
68

            
69
/// Either [ReprInitError] | [ReprInstantiateError] | [ReprSelectError]
70
#[derive(Debug, Error)]
71
pub enum ReferenceReprError {
72
    #[error(transparent)]
73
    Init(#[from] ReprInitError),
74
    #[error(transparent)]
75
    Instantiate(#[from] ReprInstantiateError),
76
    #[error(transparent)]
77
    Select(#[from] ReprSelectError),
78
}
79

            
80
impl From<ReprError> for ReferenceReprError {
81
    fn from(e: ReprError) -> Self {
82
        match e {
83
            ReprError::Init(e) => Self::Init(e),
84
            ReprError::Instantiate(e) => Self::Instantiate(e),
85
        }
86
    }
87
}
88

            
89
#[derive(Debug, Error)]
90
pub enum ReprDownError {
91
    /// The given literal cannot be represented by this representation
92
    #[error("unexpected value `{}`{}", .0, if .1.is_empty() { String::from("") } else { format!(": {}", .1) })]
93
    BadValue(Literal, String),
94
    /// Can't go down for a different reason
95
    #[error(transparent)]
96
    Other(#[from] anyhow::Error),
97
}
98

            
99
#[derive(Debug, Error)]
100
pub enum ReprUpError {
101
    /// Looking up a representation variable failed
102
    #[error("no value found for `{}`", .0.name())]
103
    NotFound(DeclarationPtr),
104
    /// Lookup succeeded but the value is not what we expected
105
    #[error("value `{} = {}` is not allowed by domain {}", .0.name(), .1, .2)]
106
    BadDomain(DeclarationPtr, Literal, DomainPtr),
107
    /// Can't go up for a different reason
108
    #[error(transparent)]
109
    Other(#[from] anyhow::Error),
110
}
111

            
112
#[derive(Debug, Error)]
113
pub enum ReprSelectError {
114
    #[error("representation `{}` does not exist for variable `{}`", .1, .0.name())]
115
    DoesNotExist(DeclarationPtr, &'static str),
116
    #[error("this reference already has representation `{}`", .0.name())]
117
    AlreadySelected(&'static dyn ReprRuleStored),
118
}