use crate::model;
use std::env;
use std::path;
pub fn main(
configuration: &model::Configuration,
get_environment_variable: &dyn Fn(&str) -> Result<String, env::VarError>,
) -> model::Result<path::PathBuf> {
if configuration.base_folder.is_absolute() {
Ok(configuration.base_folder.clone())
} else {
let mut base_folder = get_root_folder(configuration, get_environment_variable)?;
base_folder.push(&configuration.base_folder);
Ok(base_folder)
}
}
fn get_root_folder(
configuration: &model::Configuration,
get_environment_variable: &dyn Fn(&str) -> Result<String, env::VarError>,
) -> model::Result<path::PathBuf> {
let name = &configuration.root_folder_variable;
match get_environment_variable(name) {
Err(source) => Err(model::Error::EnvironmentVariable {
name: name.clone(),
source,
}),
Ok(folder) => Ok(path::PathBuf::from(folder)),
}
}
#[cfg(test)]
mod tests {
use super::*;
mod given_base_folder_is_absolute {
use super::*;
use std::fs;
#[test]
fn handles() {
let base_folder = fs::canonicalize(".").unwrap();
assert!(base_folder.is_absolute());
let actual = main(
&model::Configuration {
base_folder: base_folder.clone(),
..model::stubs::configuration()
},
&|_| unreachable!(),
);
let actual = actual.unwrap();
let expected = base_folder;
assert_eq!(actual, expected);
}
}
mod given_base_folder_is_relative {
use super::*;
#[test]
fn given_environment_variable_it_handles_concatenation() {
let actual = main(
&model::Configuration {
base_folder: path::PathBuf::from("b/c"),
root_folder_variable: String::from("ROOT_FOLDER"),
..model::stubs::configuration()
},
&|name| {
Ok(String::from(if name == "ROOT_FOLDER" {
"/a"
} else {
unreachable!()
}))
},
);
let actual = actual.unwrap();
let expected = path::PathBuf::from("/a/b/c");
assert_eq!(actual, expected);
}
#[test]
fn given_no_such_environment_variable_it_errs() {
let actual = main(
&model::Configuration {
base_folder: path::PathBuf::from("a/b"),
root_folder_variable: String::from("ROOT_FOLDER"),
..model::stubs::configuration()
},
&|_| Err(env::VarError::NotPresent),
);
let actual = actual.unwrap_err();
let expected = model::Error::EnvironmentVariable {
name: String::from("ROOT_FOLDER"),
source: env::VarError::NotPresent,
};
assert_eq!(actual, expected);
}
}
}