wasm_js/
utils.rs

1//! Utility functions for commands.
2use anyhow::Result;
3use flate2::write::ZlibEncoder;
4use flate2::Compression;
5use std::fs::{self, File};
6use std::io::{self, Write};
7use std::path::{Path, PathBuf};
8use std::time::Duration;
9
10#[cfg(windows)]
11const SYS_LINE_ENDING: &'static str = "\r\n";
12#[cfg(not(windows))]
13const SYS_LINE_ENDING: &'static str = "\n";
14
15/// If an explicit path is given, then use it, otherwise assume the current
16/// directory is the crate path.
17pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf> {
18    match path {
19        Some(p) => Ok(p),
20        None => find_manifest_from_cwd(),
21    }
22}
23
24/// Search up the path for the manifest file from the current working directory
25/// If we don't find the manifest file then return back the current working directory
26/// to provide the appropriate error
27fn find_manifest_from_cwd() -> Result<PathBuf> {
28    let mut parent_path = std::env::current_dir()?;
29    let mut manifest_path = parent_path.join("Cargo.toml");
30    loop {
31        if !manifest_path.is_file() {
32            if parent_path.pop() {
33                manifest_path = parent_path.join("Cargo.toml");
34            } else {
35                return Ok(PathBuf::from("."));
36            }
37        } else {
38            return Ok(parent_path);
39        }
40    }
41}
42
43/// Construct our `dist` directory in the crate.
44pub fn create_output_dir(out_dir: &Path) -> Result<()> {
45    fs::create_dir_all(&out_dir)?;
46    Ok(())
47}
48
49/// Get wasm-pack's binary cache.
50pub fn get_install_cache(spec: &Option<String>) -> Result<binary_install::Cache> {
51    if let Some(path) = spec {
52        Ok(binary_install::Cache::at(Path::new(&path)))
53    } else {
54        binary_install::Cache::new("wasm-js")
55    }
56}
57
58/// Render a `Duration` to a form suitable for display on a console
59pub fn elapsed(duration: Duration) -> String {
60    let secs = duration.as_secs();
61
62    if secs >= 60 {
63        format!("{}m {:02}s", secs / 60, secs % 60)
64    } else {
65        format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000)
66    }
67}
68
69/// Reads a file from `input_path` and returns its contents compressed using DEFLATE
70/// as an in-memory vector of bytes (`Vec<u8>`).
71pub fn read_and_compress<W: Write>(out: W, input_path: &Path) -> Result<()> {
72    let mut encoder = ZlibEncoder::new(out, Compression::best());
73    let mut input_file = File::open(input_path)?;
74    io::copy(&mut input_file, &mut encoder)?;
75    encoder.finish()?;
76    Ok(())
77}
78
79pub trait StrUtils {
80    fn to_os_bytes(self: &Self) -> Vec<u8>;
81}
82
83impl StrUtils for str {
84    fn to_os_bytes(self: &Self) -> Vec<u8> {
85        self.replace("\r\n", "\n")
86            .replace("\r", "\n")
87            .replace("\n", SYS_LINE_ENDING)
88            .as_bytes()
89            .to_vec()
90    }
91}