epoint_io/epoint/
write.rs

1use crate::Error::{InvalidFileExtension, NoFileName};
2use crate::epoint::write_impl::write_epoint_format;
3use crate::epoint::{FILE_EXTENSION_EPOINT_FORMAT, FILE_EXTENSION_EPOINT_TAR_FORMAT};
4use crate::error::Error;
5use chrono::{DateTime, Utc};
6use epoint_core::PointCloud;
7use std::fs::{File, OpenOptions};
8use std::io::Write;
9use std::path::Path;
10
11pub const DEFAULT_COMPRESSION_LEVEL: i32 = 10;
12
13/// `EpointWriter` sets up a writer for the custom reader data structure.
14///
15#[derive(Debug, Clone)]
16pub struct EpointWriter<W: Write> {
17    writer: W,
18    compression_level: Option<i32>,
19    time: Option<DateTime<Utc>>,
20}
21
22impl<W: Write> EpointWriter<W> {
23    pub fn new(writer: W) -> Self {
24        Self {
25            writer,
26            compression_level: Some(DEFAULT_COMPRESSION_LEVEL),
27            time: None,
28        }
29    }
30
31    pub fn with_compressed(mut self, compressed: bool) -> Self {
32        if compressed {
33            self.compression_level = Some(DEFAULT_COMPRESSION_LEVEL);
34        } else {
35            self.compression_level = None;
36        }
37        self
38    }
39
40    pub fn with_time(mut self, time: Option<DateTime<Utc>>) -> Self {
41        self.time = time;
42        self
43    }
44
45    pub fn finish(self, point_cloud: PointCloud) -> Result<(), Error> {
46        write_epoint_format(self.writer, point_cloud, self.compression_level, self.time)?;
47
48        Ok(())
49    }
50}
51
52impl EpointWriter<File> {
53    pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
54        let file_name_str = path
55            .as_ref()
56            .file_name()
57            .ok_or(NoFileName())?
58            .to_string_lossy()
59            .to_lowercase();
60        if !file_name_str.ends_with(FILE_EXTENSION_EPOINT_TAR_FORMAT)
61            && !file_name_str.ends_with(FILE_EXTENSION_EPOINT_FORMAT)
62        {
63            return Err(InvalidFileExtension(file_name_str.to_string()));
64        }
65
66        let file = OpenOptions::new()
67            .create(true)
68            .write(true)
69            .truncate(true)
70            .open(path)?;
71        Ok(Self::new(file))
72    }
73}