axiolid_mesh_hidden_lines_contract/
error.rs1use core::fmt;
4
5use axiolid_contracts::GeomError;
6
7use crate::MeshId;
8
9#[derive(Debug, Clone, PartialEq)]
18#[non_exhaustive]
19pub struct HiddenLineError {
20 pub mesh: Option<MeshId>,
22 pub error: GeomError,
24}
25
26impl HiddenLineError {
27 pub const fn request(error: GeomError) -> Self {
29 Self { mesh: None, error }
30 }
31
32 pub const fn mesh(mesh: MeshId, error: GeomError) -> Self {
34 Self {
35 mesh: Some(mesh),
36 error,
37 }
38 }
39}
40
41#[derive(Debug, Clone, PartialEq)]
48#[non_exhaustive]
49pub struct RefusedMesh {
50 pub mesh: MeshId,
52 pub error: GeomError,
54}
55
56impl RefusedMesh {
57 pub const fn new(mesh: MeshId, error: GeomError) -> Self {
59 Self { mesh, error }
60 }
61}
62
63impl From<GeomError> for HiddenLineError {
64 fn from(error: GeomError) -> Self {
65 Self::request(error)
66 }
67}
68
69impl fmt::Display for HiddenLineError {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match self.mesh {
72 Some(MeshId(id)) => write!(f, "mesh {id}: {}", self.error),
73 None => fmt::Display::fmt(&self.error, f),
74 }
75 }
76}
77
78impl std::error::Error for HiddenLineError {
79 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
80 Some(&self.error)
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use std::error::Error;
87
88 use super::*;
89
90 #[test]
91 fn display_prefixes_the_mesh_only_when_there_is_one() {
92 let inner = GeomError::NotManifold("edge 0-1 has 3 triangles".into());
93 let plain = HiddenLineError::request(inner.clone());
94 assert_eq!(plain.to_string(), inner.to_string());
95 let named = HiddenLineError::mesh(MeshId(7), inner.clone());
96 assert_eq!(named.to_string(), format!("mesh 7: {inner}"));
97 }
98
99 #[test]
100 fn conversion_and_source_keep_the_geometry_error() {
101 let error: HiddenLineError = GeomError::Cancelled.into();
102 assert_eq!(error.mesh, None);
103 assert_eq!(error.error, GeomError::Cancelled);
104 let source = error.source().expect("source").to_string();
105 assert_eq!(source, GeomError::Cancelled.to_string());
106 }
107}