Skip to main content

conspire/domain/block/element/
mod.rs

1pub(crate) mod solid;
2#[cfg(test)]
3pub(crate) mod test;
4
5use crate::math::{Style, StyledError, assert::AssertionError};
6use std::{
7    fmt::{self, Debug, Display, Formatter},
8    marker::PhantomData,
9};
10
11pub trait Elements
12where
13    Self: Debug,
14{
15    fn node_neighbors(&self, neighbors: &mut [Vec<usize>]);
16}
17
18pub trait ElementKind {
19    const NAME: &'static str;
20}
21
22pub enum ElementError<K> {
23    Upstream(String, String, PhantomData<K>),
24}
25
26impl<K> ElementError<K> {
27    pub fn upstream(error: impl Display, context: &(impl Debug + ?Sized)) -> Self {
28        Self::Upstream(format!("{error}"), format!("{context:?}"), PhantomData)
29    }
30}
31
32impl<K: ElementKind> From<ElementError<K>> for AssertionError {
33    fn from(error: ElementError<K>) -> Self {
34        Self {
35            message: error.to_string(),
36        }
37    }
38}
39
40impl<K: ElementKind> StyledError for ElementError<K> {
41    fn message(&self, style: &Style) -> String {
42        let c = style.frame;
43        match self {
44            Self::Upstream(error, element, _) => format!(
45                "{error}{c}\n\
46                In {}: {element}.",
47                K::NAME
48            ),
49        }
50    }
51}
52
53impl<K: ElementKind> Debug for ElementError<K> {
54    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
55        let style = Style::detect();
56        write!(
57            f,
58            "\n{}\n{}{}{}\n",
59            self.message(&style),
60            style.footer,
61            crate::math::defeat_message(),
62            style.reset
63        )
64    }
65}
66
67impl<K: ElementKind> Display for ElementError<K> {
68    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
69        let style = Style::detect();
70        write!(f, "{}{}", self.message(&style), style.reset)
71    }
72}
73
74impl<K: ElementKind> std::error::Error for ElementError<K> {}