use std::collections::HashMap;
pub struct OutputEntry<'a>(pub &'a str, pub &'a str);
pub trait Formatter<'a, I: IntoIterator<Item = OutputEntry<'a>>> {
fn format(&self, entries: I) -> String;
}
pub struct EnvFormatter {}
impl EnvFormatter {
pub fn new() -> Self {
EnvFormatter {}
}
}
impl<'a, I: IntoIterator<Item = OutputEntry<'a>>> Formatter<'a, I> for EnvFormatter {
fn format(&self, entries: I) -> String {
let mut output = String::new();
for entry in entries {
output.push_str(&format!("{}={}\n", entry.0, entry.1));
}
output
}
}
pub struct ShellFormatter {}
impl ShellFormatter {
pub fn new() -> Self {
ShellFormatter {}
}
}
impl<'a, I: IntoIterator<Item = OutputEntry<'a>>> Formatter<'a, I> for ShellFormatter {
fn format(&self, entries: I) -> String {
let mut output = String::new();
for entry in entries {
output.push_str(&format!("export {}={}\n", entry.0, entry.1));
}
output
}
}
pub struct JsonFormatter {}
impl JsonFormatter {
pub fn new() -> Self {
JsonFormatter {}
}
}
impl<'a, I: IntoIterator<Item = OutputEntry<'a>>> Formatter<'a, I> for JsonFormatter {
fn format(&self, entries: I) -> String {
let mut output = HashMap::new();
for entry in entries {
output.insert(entry.0, entry.1);
}
serde_json::to_string(&output).expect("HashMap should be serialized to JSON") + "\n"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_env_output() {
let input = vec![OutputEntry("KEY1", "value1"), OutputEntry("KEY2", "value2")];
let formatter = EnvFormatter::new();
let result = formatter.format(input);
assert_eq!(result, "KEY1=value1\nKEY2=value2\n")
}
#[test]
fn test_shell_output() {
let input = vec![OutputEntry("KEY1", "value1"), OutputEntry("KEY2", "value2")];
let formatter = ShellFormatter::new();
let result = formatter.format(input);
assert_eq!(result, "export KEY1=value1\nexport KEY2=value2\n")
}
#[test]
fn test_json_output() {
let input = vec![OutputEntry("KEY1", "value1"), OutputEntry("KEY2", "value2")];
let formatter = JsonFormatter::new();
let result = formatter.format(input);
let mut expected = HashMap::new();
expected.insert("KEY1", "value1");
expected.insert("KEY2", "value2");
assert_eq!(
serde_json::from_str::<serde_json::Value>(&result).unwrap(),
serde_json::to_value(expected).unwrap()
)
}
}