honeycomb_core/cmap/builder/
structure.rs1use std::fs::File;
2use std::io::Read;
3
4use thiserror::Error;
5use vtkio::Vtk;
6
7use crate::attributes::{AttrStorageManager, AttributeBind};
8use crate::cmap::{CMap2, CMap3};
9use crate::geometry::CoordsFloat;
10
11use super::io::CMapFile;
12
13#[derive(Error, Debug, PartialEq, Eq)]
18pub enum BuilderError {
19 #[error("error parsing a value in one of the cmap file section - {0}")]
22 BadValue(&'static str),
23 #[error("error parsing the cmap file meta section - {0}")]
25 BadMetaData(&'static str),
26 #[error("duplicated section in cmap file - {0}")]
28 DuplicatedSection(String),
29 #[error("inconsistent data - {0}")]
31 InconsistentData(&'static str),
32 #[error("required section missing in cmap file - {0}")]
34 MissingSection(&'static str),
35 #[error("unknown header in cmap file - {0}")]
37 UnknownHeader(String),
38
39 #[error("invalid/corrupted data in the vtk file - {0}")]
42 BadVtkData(&'static str),
43 #[error("unsupported data in the vtk file - {0}")]
45 UnsupportedVtkData(&'static str),
46}
47
48pub struct CMapBuilder<const D: usize> {
68 builder_kind: BuilderType,
69 attributes: AttrStorageManager,
70}
71
72enum BuilderType {
73 CMap(CMapFile),
74 FreeDarts(usize),
75 Vtk(Vtk),
76}
77
78#[doc(hidden)]
79pub trait Builder<T: CoordsFloat> {
80 type MapType;
81 fn build(self) -> Result<Self::MapType, BuilderError>;
82}
83
84impl<T: CoordsFloat> Builder<T> for CMapBuilder<2> {
85 type MapType = CMap2<T>;
86
87 fn build(self) -> Result<Self::MapType, BuilderError> {
88 match self.builder_kind {
89 BuilderType::CMap(cfile) => super::io::build_2d_from_cmap_file(cfile, self.attributes),
90 BuilderType::FreeDarts(n_darts) => Ok(CMap2::new_with_undefined_attributes(
91 n_darts,
92 self.attributes,
93 )),
94 BuilderType::Vtk(vfile) => super::io::build_2d_from_vtk(vfile, self.attributes),
95 }
96 }
97}
98
99impl<T: CoordsFloat> Builder<T> for CMapBuilder<3> {
100 type MapType = CMap3<T>;
101
102 fn build(self) -> Result<Self::MapType, BuilderError> {
103 match self.builder_kind {
104 BuilderType::CMap(cfile) => super::io::build_3d_from_cmap_file(cfile, self.attributes),
105 BuilderType::FreeDarts(n_darts) => Ok(CMap3::new_with_undefined_attributes(
106 n_darts,
107 self.attributes,
108 )),
109 BuilderType::Vtk(_vfile) => unimplemented!(),
110 }
111 }
112}
113impl<const D: usize> CMapBuilder<D> {
115 #[must_use = "unused builder object"]
118 pub fn from_n_darts_and_attributes(n_darts: usize, other: Self) -> Self {
119 Self {
120 builder_kind: BuilderType::FreeDarts(n_darts),
121 attributes: other.attributes,
122 }
123 }
124
125 #[must_use = "unused builder object"]
127 pub fn from_n_darts(n_darts: usize) -> Self {
128 Self {
129 builder_kind: BuilderType::FreeDarts(n_darts),
130 attributes: AttrStorageManager::default(),
131 }
132 }
133
134 #[must_use = "unused builder object"]
140 pub fn from_cmap_file(file_path: impl AsRef<std::path::Path> + std::fmt::Debug) -> Self {
141 let mut f = File::open(file_path).expect("E: could not open specified file");
142 let mut buf = String::new();
143 f.read_to_string(&mut buf)
144 .expect("E: could not read content from file");
145 let cmap_file = CMapFile::try_from(buf).unwrap();
146
147 Self {
148 builder_kind: BuilderType::CMap(cmap_file),
149 attributes: AttrStorageManager::default(),
150 }
151 }
152
153 #[must_use = "unused builder object"]
159 pub fn from_vtk_file(file_path: impl AsRef<std::path::Path> + std::fmt::Debug) -> Self {
160 let vtk_file =
161 Vtk::import(file_path).unwrap_or_else(|e| panic!("E: failed to load file: {e:?}"));
162
163 Self {
164 builder_kind: BuilderType::Vtk(vtk_file),
165 attributes: AttrStorageManager::default(),
166 }
167 }
168
169 #[must_use = "unused builder object"]
182 pub fn add_attribute<A: AttributeBind + 'static>(mut self) -> Self {
183 self.attributes.add_storage::<A>(1);
184 self
185 }
186
187 #[allow(clippy::missing_errors_doc)]
188 #[allow(private_interfaces, private_bounds)]
205 pub fn build<T: CoordsFloat>(self) -> Result<<Self as Builder<T>>::MapType, BuilderError>
206 where
207 Self: Builder<T>,
208 {
209 Builder::build(self)
210 }
211}