use super::toml as fzf_make_toml;
use crate::model;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Serialize, Deserialize, Clone, PartialEq)]
struct Histories {
history: Vec<History>,
}
impl Histories {
fn into_histories(self) -> fzf_make_toml::Histories {
let mut result: Vec<fzf_make_toml::History> = vec![];
for h in self.history.clone() {
let mut commands: Vec<fzf_make_toml::HistoryCommand> = vec![];
for c in h.executed_targets {
commands.push(fzf_make_toml::HistoryCommand::new(model::runner_type::RunnerType::Make, c));
}
let mut makefile_path = PathBuf::from(h.path);
makefile_path.pop();
result.push(fzf_make_toml::History::new(makefile_path, commands));
}
fzf_make_toml::Histories::new(result)
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename(deserialize = "history"))]
#[serde(rename_all = "kebab-case")]
struct History {
path: String,
executed_targets: Vec<String>,
}
pub fn parse_history(content: String) -> Result<fzf_make_toml::Histories> {
toml::from_str(&content)
.map(|h: Histories| h.into_histories())
.map_err(|e| e.into())
}
#[cfg(test)]
mod test {
use super::*;
use crate::{file::toml as fzf_make_toml, model::runner_type};
use pretty_assertions::assert_eq;
#[test]
fn into_histories_test() {
struct Case {
title: &'static str,
before: Histories,
after: fzf_make_toml::Histories,
}
let cases = vec![Case {
title: "Success",
before: Histories {
history: vec![History {
path: "path/Makefile".to_string(),
executed_targets: vec!["command1".to_string(), "command2".to_string()],
}],
},
after: fzf_make_toml::Histories::new(vec![fzf_make_toml::History::new(
PathBuf::from("path"),
vec![
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "command1".to_string()),
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "command2".to_string()),
],
)]),
}];
for case in cases {
assert_eq!(case.after, case.before.into_histories(), "\nFailed: 🚨{:?}🚨\n", case.title,)
}
}
#[test]
fn parse_history_test() {
struct Case {
title: &'static str,
content: String,
expect: Result<fzf_make_toml::Histories>,
}
let cases = vec![
Case {
title: "Success",
content: r#"
[[history]]
path = "/Users/user/code/fzf-make/Makefile"
executed-targets = ["test", "check", "spell-check"]
[[history]]
path = "/Users/user/code/golang/go-playground/Makefile"
executed-targets = ["run", "echo1"]
"#
.to_string(),
expect: Ok(fzf_make_toml::Histories::new(vec![
fzf_make_toml::History::new(
PathBuf::from("/Users/user/code/fzf-make"),
vec![
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "test".to_string()),
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "check".to_string()),
fzf_make_toml::HistoryCommand::new(
runner_type::RunnerType::Make,
"spell-check".to_string(),
),
],
),
fzf_make_toml::History::new(
PathBuf::from("/Users/user/code/golang/go-playground"),
vec![
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "run".to_string()),
fzf_make_toml::HistoryCommand::new(runner_type::RunnerType::Make, "echo1".to_string()),
],
),
])),
},
Case {
title: "Error",
content: r#"
"#
.to_string(),
expect: Err(anyhow::anyhow!(
"TOML parse error at line 1, column 1\n |\n1 | \n | ^\nmissing field `history`\n"
)),
},
];
for case in cases {
match case.expect {
Ok(e) => assert_eq!(e, parse_history(case.content).unwrap(), "\nFailed: 🚨{:?}🚨\n", case.title,),
Err(err) => assert_eq!(
err.to_string(),
parse_history(case.content).unwrap_err().to_string(),
"\nFailed: 🚨{:?}🚨\n",
case.title,
),
}
}
}
}