epub_builder/
zip_command_or_library.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with
3// this file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use crate::zip::Zip;
6use crate::Result;
7use crate::ZipCommand;
8use crate::ZipLibrary;
9
10use std::io::Read;
11use std::io::Write;
12use std::path::Path;
13
14/// Wrapper around either a ZipCommand or a ZipLibrary
15///
16/// Allows to create an EpubBuilder that can decide at runtime which to use.
17pub enum ZipCommandOrLibrary {
18    /// Command variant
19    Command(ZipCommand),
20    /// Library variant
21    Library(ZipLibrary),
22}
23
24impl Zip for ZipCommandOrLibrary {
25    fn write_file<P: AsRef<Path>, R: Read>(&mut self, path: P, content: R) -> Result<()> {
26        match self {
27            ZipCommandOrLibrary::Command(command) => command.write_file(path, content),
28            ZipCommandOrLibrary::Library(library) => library.write_file(path, content),
29        }
30    }
31
32    fn generate<W: Write>(self, to: W) -> Result<()> {
33        match self {
34            ZipCommandOrLibrary::Command(command) => command.generate(to),
35            ZipCommandOrLibrary::Library(library) => library.generate(to),
36        }
37    }
38}
39
40impl ZipCommandOrLibrary {
41    /// Try to create a ZipCommand using `command`. If running `command` fails on the system,
42    /// fall back to `ZipLibrary`.
43    pub fn new(command: &str) -> Result<ZipCommandOrLibrary> {
44        ZipCommand::new()
45            .map(|mut z| {
46                z.command(command);
47                z
48            })
49            .and_then(|z| z.test().map(|_| z))
50            .map(ZipCommandOrLibrary::Command)
51            .or_else(|_| ZipLibrary::new().map(ZipCommandOrLibrary::Library))
52    }
53}