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}