wasmer_compiler_cli/
utils.rs

1//! Utility functions for the WebAssembly module
2use anyhow::{bail, Context, Result};
3use is_terminal::IsTerminal;
4use std::path::PathBuf;
5use std::{env, path::Path};
6
7/// Whether or not Wasmer should print with color
8pub fn wasmer_should_print_color() -> bool {
9    env::var("WASMER_COLOR")
10        .ok()
11        .and_then(|inner| inner.parse::<bool>().ok())
12        .unwrap_or_else(|| std::io::stdout().is_terminal())
13}
14
15fn retrieve_alias_pathbuf(alias: &str, real_dir: &str) -> Result<(String, PathBuf)> {
16    let pb = Path::new(real_dir)
17        .canonicalize()
18        .with_context(|| format!("Unable to get the absolute path for \"{real_dir}\""))?;
19
20    if let Ok(pb_metadata) = pb.metadata() {
21        if !pb_metadata.is_dir() {
22            bail!("\"{real_dir}\" exists, but it is not a directory");
23        }
24    } else {
25        bail!("Directory \"{real_dir}\" does not exist");
26    }
27
28    Ok((alias.to_string(), pb))
29}
30
31/// Parses a mapdir from a string
32pub fn parse_mapdir(entry: &str) -> Result<(String, PathBuf)> {
33    // We try first splitting by `::`
34    if let [alias, real_dir] = entry.split("::").collect::<Vec<&str>>()[..] {
35        retrieve_alias_pathbuf(alias, real_dir)
36    }
37    // And then we try splitting by `:` (for compatibility with previous API)
38    else if let [alias, real_dir] = entry.split(':').collect::<Vec<&str>>()[..] {
39        retrieve_alias_pathbuf(alias, real_dir)
40    } else {
41        bail!(
42            "Directory mappings must consist of two paths separate by a `::` or `:`. Found {}",
43            &entry
44        )
45    }
46}
47
48/// Parses an environment variable.
49pub fn parse_envvar(entry: &str) -> Result<(String, String)> {
50    let entry = entry.trim();
51
52    match entry.find('=') {
53        None => bail!(
54            "Environment variable must be of the form `<name>=<value>`; found `{}`",
55            &entry
56        ),
57
58        Some(0) => bail!(
59            "Environment variable is not well formed, the `name` is missing in `<name>=<value>`; got `{}`",
60            &entry
61        ),
62
63        Some(position) if position == entry.len() - 1 => bail!(
64            "Environment variable is not well formed, the `value` is missing in `<name>=<value>`; got `{}`",
65            &entry
66        ),
67
68        Some(position) => Ok((entry[..position].into(), entry[position + 1..].into())),
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::parse_envvar;
75
76    #[test]
77    fn test_parse_envvar() {
78        assert_eq!(
79            parse_envvar("A").unwrap_err().to_string(),
80            "Environment variable must be of the form `<name>=<value>`; found `A`"
81        );
82        assert_eq!(
83            parse_envvar("=A").unwrap_err().to_string(),
84            "Environment variable is not well formed, the `name` is missing in `<name>=<value>`; got `=A`"
85        );
86        assert_eq!(
87            parse_envvar("A=").unwrap_err().to_string(),
88            "Environment variable is not well formed, the `value` is missing in `<name>=<value>`; got `A=`"
89        );
90        assert_eq!(parse_envvar("A=B").unwrap(), ("A".into(), "B".into()));
91        assert_eq!(parse_envvar("   A=B\t").unwrap(), ("A".into(), "B".into()));
92        assert_eq!(
93            parse_envvar("A=B=C=D").unwrap(),
94            ("A".into(), "B=C=D".into())
95        );
96    }
97}