eimage_io/eimage/
write.rs

1use crate::Error;
2use crate::Error::{InvalidFileExtension, NoFileExtension};
3use crate::eimage::write_impl::write_eimage_format;
4use crate::eimage::{FILE_EXTENSION_EIMAGE_COMPRESSED, FILE_EXTENSION_EIMAGE_UNCOMPRESSED};
5use eimage_core::ImageCollection;
6use std::fs::{File, OpenOptions};
7use std::io::Write;
8use std::path::Path;
9
10pub const DEFAULT_COMPRESSION_LEVEL: i32 = 10;
11
12/// `EimageWriter` sets up a writer for the custom reader data structure.
13///
14#[derive(Debug, Clone)]
15pub struct EimageWriter<W: Write> {
16    writer: W,
17    compression_level: Option<i32>,
18}
19
20impl<W: Write> EimageWriter<W> {
21    pub fn new(writer: W) -> Self {
22        Self {
23            writer,
24            compression_level: Some(DEFAULT_COMPRESSION_LEVEL),
25        }
26    }
27
28    pub fn with_compressed(mut self, compressed: bool) -> Self {
29        if compressed {
30            self.compression_level = Some(DEFAULT_COMPRESSION_LEVEL);
31        } else {
32            self.compression_level = None;
33        }
34        self
35    }
36
37    pub fn finish(self, image_collection: ImageCollection) -> Result<(), Error> {
38        write_eimage_format(self.writer, image_collection, self.compression_level)?;
39
40        Ok(())
41    }
42}
43
44impl EimageWriter<File> {
45    pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
46        let extension = path.as_ref().extension().ok_or(NoFileExtension())?;
47        if extension != FILE_EXTENSION_EIMAGE_UNCOMPRESSED
48            && extension != FILE_EXTENSION_EIMAGE_COMPRESSED
49        {
50            return Err(InvalidFileExtension(
51                extension.to_str().unwrap_or_default().to_string(),
52            ));
53        }
54
55        let file = OpenOptions::new()
56            .create(true)
57            .write(true)
58            .truncate(true)
59            .open(path)?;
60        Ok(Self::new(file))
61    }
62}