layout21utils/
error.rs

1//!
2//! # Layout21 Error-Helper Utilities
3//!
4
5/// Helper trait for re-use among our many conversion tree-walkers.
6/// Each implementer will generally have some internal state to report upon failure,
7/// which it can inject in the implementation-required `err` method.
8/// The `fail` method, provided by default, simply returns the `err` value.
9pub trait ErrorHelper {
10    type Error;
11
12    /// Create and return a [Self::Error] value.
13    fn err(&self, msg: impl Into<String>) -> Self::Error;
14    /// Return failure
15    fn fail<T>(&self, msg: impl Into<String>) -> Result<T, Self::Error> {
16        Err(self.err(msg))
17    }
18    /// Unwrap the [Option] `opt` if it is [Some], and return our error if not.
19    fn unwrap<T>(&self, opt: Option<T>, msg: impl Into<String>) -> Result<T, Self::Error> {
20        match opt {
21            Some(val) => Ok(val),
22            None => self.fail(msg),
23        }
24    }
25    /// Assert boolean condition `b`. Returns through `self.fail` if not.
26    fn assert(&self, b: bool) -> Result<(), Self::Error> {
27        match b {
28            true => Ok(()),
29            false => self.fail("assertion failed"),
30        }
31    }
32    /// Unwrap the [Result] `res`. Return through our failure method if it is [Err].
33    /// Optional method, but must be implemented to be (usefully) called.
34    /// The default implementation simply returns an error via `self.fail`.
35    fn ok<T, E>(&self, _res: Result<T, E>, msg: impl Into<String>) -> Result<T, Self::Error>
36    where
37        E: std::error::Error + 'static,
38    {
39        self.fail(msg) // Default version always fails.
40    }
41}
42/// Enumerated conversion contexts
43/// Generally used for error reporting
44#[derive(Debug, Clone)]
45pub enum ErrorContext {
46    Library(String),
47    Cell(String),
48    Abstract,
49    Impl,
50    Instance(String),
51    Array(String),
52    Units,
53    Geometry,
54    Unknown,
55}