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 inp file - {0}")]
42 BadInpData(&'static str),
43 #[error("unsupported data in the inp file - {0}")]
45 UnsupportedInpData(&'static str),
46
47 #[error("invalid/corrupted data in the vtk file - {0}")]
50 BadVtkData(&'static str),
51 #[error("unsupported data in the vtk file - {0}")]
53 UnsupportedVtkData(&'static str),
54}
55
56pub struct CMapBuilder<const D: usize> {
76 builder_kind: BuilderType,
77 attributes: AttrStorageManager,
78}
79
80enum BuilderType {
81 CMap(CMapFile),
82 FreeDarts(usize),
83 Inp(String),
84 Vtk(Vtk),
85}
86
87#[doc(hidden)]
88pub trait Builder<T: CoordsFloat> {
89 type MapType;
90 fn build(self) -> Result<Self::MapType, BuilderError>;
91}
92
93impl<T: CoordsFloat> Builder<T> for CMapBuilder<2> {
94 type MapType = CMap2<T>;
95
96 fn build(self) -> Result<Self::MapType, BuilderError> {
97 match self.builder_kind {
98 BuilderType::CMap(cfile) => super::io::build_2d_from_cmap_file(cfile, self.attributes),
99 BuilderType::FreeDarts(n_darts) => Ok(CMap2::new_with_undefined_attributes(
100 n_darts,
101 self.attributes,
102 )),
103 BuilderType::Inp(_) => unreachable!("INP input is only available for 3-maps"),
104 BuilderType::Vtk(vfile) => super::io::build_2d_from_vtk(vfile, self.attributes),
105 }
106 }
107}
108
109impl<T: CoordsFloat> Builder<T> for CMapBuilder<3> {
110 type MapType = CMap3<T>;
111
112 fn build(self) -> Result<Self::MapType, BuilderError> {
113 match self.builder_kind {
114 BuilderType::CMap(cfile) => super::io::build_3d_from_cmap_file(cfile, self.attributes),
115 BuilderType::FreeDarts(n_darts) => Ok(CMap3::new_with_undefined_attributes(
116 n_darts,
117 self.attributes,
118 )),
119 BuilderType::Inp(content) => super::io::build_3d_from_inp(&content, self.attributes),
120 BuilderType::Vtk(_vfile) => unimplemented!(),
121 }
122 }
123}
124
125impl CMapBuilder<3> {
126 #[must_use = "unused builder object"]
136 pub fn from_inp_file(file_path: impl AsRef<std::path::Path> + std::fmt::Debug) -> Self {
137 let mut f = File::open(file_path).expect("E: could not open specified file");
138 let mut content = String::new();
139 f.read_to_string(&mut content)
140 .expect("E: could not read content from file");
141
142 Self {
143 builder_kind: BuilderType::Inp(content),
144 attributes: AttrStorageManager::default(),
145 }
146 }
147}
148impl<const D: usize> CMapBuilder<D> {
150 #[must_use = "unused builder object"]
153 pub fn from_n_darts_and_attributes(n_darts: usize, other: Self) -> Self {
154 Self {
155 builder_kind: BuilderType::FreeDarts(n_darts),
156 attributes: other.attributes,
157 }
158 }
159
160 #[must_use = "unused builder object"]
162 pub fn from_n_darts(n_darts: usize) -> Self {
163 Self {
164 builder_kind: BuilderType::FreeDarts(n_darts),
165 attributes: AttrStorageManager::default(),
166 }
167 }
168
169 #[must_use = "unused builder object"]
175 pub fn from_cmap_file(file_path: impl AsRef<std::path::Path> + std::fmt::Debug) -> Self {
176 let mut f = File::open(file_path).expect("E: could not open specified file");
177 let mut buf = String::new();
178 f.read_to_string(&mut buf)
179 .expect("E: could not read content from file");
180 let cmap_file = CMapFile::try_from(buf).unwrap();
181
182 Self {
183 builder_kind: BuilderType::CMap(cmap_file),
184 attributes: AttrStorageManager::default(),
185 }
186 }
187
188 #[must_use = "unused builder object"]
194 pub fn from_vtk_file(file_path: impl AsRef<std::path::Path> + std::fmt::Debug) -> Self {
195 let vtk_file =
196 Vtk::import(file_path).unwrap_or_else(|e| panic!("E: failed to load file: {e:?}"));
197
198 Self {
199 builder_kind: BuilderType::Vtk(vtk_file),
200 attributes: AttrStorageManager::default(),
201 }
202 }
203
204 #[must_use = "unused builder object"]
217 pub fn add_attribute<A: AttributeBind + 'static>(mut self) -> Self {
218 self.attributes.add_storage::<A>(1);
219 self
220 }
221
222 #[allow(clippy::missing_errors_doc)]
223 #[allow(private_interfaces, private_bounds)]
240 pub fn build<T: CoordsFloat>(self) -> Result<<Self as Builder<T>>::MapType, BuilderError>
241 where
242 Self: Builder<T>,
243 {
244 Builder::build(self)
245 }
246}