Skip to main content

softgpu_functional/
error.rs

1//! Fail-closed functional-execution errors.
2
3use std::fmt;
4
5pub type Result<T> = std::result::Result<T, FunctionalError>;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum FunctionalError {
9    Io(String),
10    Parse(String),
11    Unsupported {
12        detail: String,
13    },
14    Validation {
15        detail: String,
16    },
17    Bounds {
18        addr: u64,
19        size: usize,
20        arena_len: usize,
21    },
22    UndefinedReg {
23        name: String,
24    },
25    StepBudgetExceeded {
26        steps: u64,
27    },
28    Internal(String),
29}
30
31impl fmt::Display for FunctionalError {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            Self::Io(s) => write!(f, "io: {s}"),
35            Self::Parse(s) => write!(f, "parse: {s}"),
36            Self::Unsupported { detail } => write!(f, "unsupported: {detail}"),
37            Self::Validation { detail } => write!(f, "validation: {detail}"),
38            Self::Bounds {
39                addr,
40                size,
41                arena_len,
42            } => write!(
43                f,
44                "bounds: addr={addr:#x} size={size} arena_len={arena_len}"
45            ),
46            Self::UndefinedReg { name } => write!(f, "undefined register '{name}'"),
47            Self::StepBudgetExceeded { steps } => {
48                write!(f, "step budget exceeded after {steps} steps")
49            }
50            Self::Internal(s) => write!(f, "internal: {s}"),
51        }
52    }
53}
54
55impl std::error::Error for FunctionalError {}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn display_covers_variants() {
63        let cases = [
64            FunctionalError::Io("x".into()),
65            FunctionalError::Parse("p".into()),
66            FunctionalError::Unsupported { detail: "u".into() },
67            FunctionalError::Validation { detail: "v".into() },
68            FunctionalError::Bounds {
69                addr: 0x10,
70                size: 4,
71                arena_len: 2,
72            },
73            FunctionalError::UndefinedReg { name: "r0".into() },
74            FunctionalError::StepBudgetExceeded { steps: 9 },
75            FunctionalError::Internal("i".into()),
76        ];
77        for err in cases {
78            let s = err.to_string();
79            assert!(!s.is_empty(), "{err:?}");
80        }
81    }
82}