1use crate::error::Error;
2
3use epoint_core::point_cloud::PointCloud;
4
5use crate::Error::{InvalidFileExtension, NoFileExtension};
6use crate::FILE_EXTENSION_XYZ_FORMAT;
7use crate::xyz::DEFAULT_XYZ_SEPARATOR;
8use crate::xyz::read_impl::read_point_cloud_from_xyz_file;
9use std::path::{Path, PathBuf};
10
11#[derive(Debug, Clone)]
14pub struct XyzReader {
15 path: PathBuf,
16 separator: u8,
17}
18
19impl XyzReader {
20 pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
21 Ok(Self {
22 path: path.as_ref().to_owned(),
23 separator: DEFAULT_XYZ_SEPARATOR,
24 })
25 }
26
27 pub fn with_separator(mut self, separator: u8) -> Self {
28 self.separator = separator;
29 self
30 }
31
32 pub fn finish(self) -> Result<PointCloud, Error> {
33 let extension = self.path.extension().ok_or(NoFileExtension())?;
34 if extension != FILE_EXTENSION_XYZ_FORMAT {
35 return Err(InvalidFileExtension(
36 extension.to_str().unwrap_or_default().to_string(),
37 ));
38 }
39
40 let point_cloud = read_point_cloud_from_xyz_file(&self.path, self.separator)?;
41 Ok(point_cloud)
42 }
43}