conspire/domain/block/element/
mod.rs1pub(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> {}