use std::{fs::File, io};
use crate::{output::Output, parser::EnvParser, variable::Variables};
use anyhow::Result;
pub struct ShellOutput;
impl Output for ShellOutput {
fn format(&self, variables: Variables) -> Result<String> {
let mut output = String::new();
for var in variables {
output.push_str(&format!(
"export {}={}\n",
var.key,
serde_json::to_string(&var.value)?
));
}
Ok(output)
}
fn load_existing(&self, file: File) -> Result<Variables> {
let input = io::read_to_string(file)?;
let mut variables = EnvParser::parse_variables(&input)?;
variables.iter_mut().for_each(|v| v.promote_default());
Ok(variables)
}
}
#[cfg(test)]
mod tests {
use std::fs;
use crate::variable::Variable;
use super::*;
fn write_temp(name: &str, contents: &str) -> std::path::PathBuf {
let path = std::env::temp_dir().join(format!("awsm_env_test_{}", name));
fs::write(&path, contents).unwrap();
path
}
#[test]
fn test_shell_output() {
let input: Variables = vec![
Variable {
key: "KEY1".to_string(),
required: true,
value: Some("value1".to_string()),
..Default::default()
},
Variable {
key: "KEY2".to_string(),
required: true,
value: Some("val\"ue2".to_string()),
..Default::default()
},
]
.into();
let output = ShellOutput;
let result = output.format(input).unwrap();
assert_eq!(
result,
"export KEY1=\"value1\"\nexport KEY2=\"val\\\"ue2\"\n"
)
}
#[test]
fn test_shell_load_existing() {
let path = write_temp(
"shell_load.sh",
"export KEY1=\"value1\"\nexport KEY2=\"val\\\"ue2\"\n",
);
let result = ShellOutput
.load_existing(File::open(&path).unwrap())
.unwrap();
let expected: Variables = vec![
Variable {
key: "KEY1".to_string(),
required: true,
value: Some("value1".to_string()),
..Default::default()
},
Variable {
key: "KEY2".to_string(),
required: true,
value: Some("val\"ue2".to_string()),
..Default::default()
},
]
.into();
assert_eq!(result, expected);
let _ = fs::remove_file(&path);
}
}