mod text;
mod verdict;
pub use text::{usage, version};
pub use verdict::{Stream, Verdict};
#[derive(Debug)]
pub enum Decided {
Say(Verdict),
Entries,
Window,
Start { address: String, goal: String },
Ask(serde_json::Value),
}
pub fn run(args: Vec<String>) -> Decided {
let words: Vec<&str> = args.iter().map(String::as_str).collect();
match words.as_slice() {
["entries"] => Decided::Entries,
["ask", envelope] => ask(envelope),
["help" | "--help" | "-h"] => Decided::Say(Verdict::ok(usage())),
["help", verb] => Decided::Say(match crate::verbs::help::page(verb) {
Ok(page) => Verdict::ok(page),
Err(refusal) => Verdict::refused(refusal),
}),
["--version" | "-V"] => Decided::Say(Verdict::ok(version())),
["ask"] => Decided::Say(Verdict::refused(
"`lernie ask` wants one gesture envelope".to_owned(),
)),
["start", address, goal] => Decided::Start {
address: (*address).to_owned(),
goal: (*goal).to_owned(),
},
["start", ..] => Decided::Say(Verdict::refused(
"`lernie start` takes a workspace and a goal — usage: lernie start <workspace> <goal>"
.to_owned(),
)),
[] => Decided::Window,
[word, arguments @ ..] => typed(word, arguments),
}
}
fn ask(text: &str) -> Decided {
match crate::envelope::parse(text) {
Ok(envelope) => Decided::Ask(envelope),
Err(refusal) => Decided::Say(Verdict::refused(refusal)),
}
}
fn typed(word: &str, arguments: &[&str]) -> Decided {
let Some(verb) = crate::verbs::find(word) else {
return Decided::Say(Verdict::refused(format!(
"unrecognised argument: {}",
std::iter::once(word)
.chain(arguments.iter().copied())
.collect::<Vec<&str>>()
.join(" ")
)));
};
match verb.envelope(arguments.iter().map(|a| (*a).to_owned()).collect()) {
Ok(envelope) => Decided::Ask(envelope),
Err(refusal) => Decided::Say(Verdict::refused(refusal)),
}
}
#[cfg(test)]
mod tests;