use crate::cli::SubCmd;
use crate::command;
use crate::config::YamlConfig;
use crate::constants::cmd;
pub enum ParseResult {
Matched(SubCmd),
Handled,
NotFound,
}
pub fn execute_interactive_command(args: &[String], config: &mut YamlConfig) {
if args.is_empty() {
return;
}
let cmd_str = &args[0];
if cmd::EXIT.contains(&cmd_str.as_str()) {
command::system::handle_exit();
return;
}
match parse_interactive_command(args) {
ParseResult::Matched(subcmd) => {
command::dispatch(subcmd, config);
}
ParseResult::Handled => {}
ParseResult::NotFound => {
command::open::handle_open(args, config);
}
}
}
pub fn parse_interactive_command(args: &[String]) -> ParseResult {
if args.is_empty() {
return ParseResult::NotFound;
}
let cmd = args[0].as_str();
let rest = &args[1..];
let is = |names: &[&str]| names.contains(&cmd);
if is(cmd::SET) {
if rest.is_empty() {
crate::usage!("set <alias> <path>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Set {
alias: rest[0].clone(),
path: rest[1..].to_vec(),
})
} else if is(cmd::REMOVE) {
match rest.first() {
Some(alias) => ParseResult::Matched(SubCmd::Remove {
alias: alias.clone(),
}),
None => {
crate::usage!("rm <alias>");
ParseResult::Handled
}
}
} else if is(cmd::RENAME) {
if rest.len() < 2 {
crate::usage!("rename <alias> <new_alias>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Rename {
alias: rest[0].clone(),
new_alias: rest[1].clone(),
})
} else if is(cmd::MODIFY) {
if rest.is_empty() {
crate::usage!("mf <alias> <new_path>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Modify {
alias: rest[0].clone(),
path: rest[1..].to_vec(),
})
} else if is(cmd::TAG) {
if rest.len() < 2 {
crate::usage!("tag <alias> <category>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Tag {
alias: rest[0].clone(),
category: rest[1].clone(),
})
} else if is(cmd::UNTAG) {
if rest.len() < 2 {
crate::usage!("untag <alias> <category>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Untag {
alias: rest[0].clone(),
category: rest[1].clone(),
})
} else if is(cmd::LIST) {
ParseResult::Matched(SubCmd::List {
part: rest.first().cloned(),
})
} else if is(cmd::CONTAIN) {
if rest.is_empty() {
crate::usage!("contain <alias> [sections]");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Contain {
alias: rest[0].clone(),
containers: rest.get(1).cloned(),
})
} else if is(cmd::LOG) {
if rest.len() < 2 {
crate::usage!("log mode <verbose|concise>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Log {
key: rest[0].clone(),
value: rest[1].clone(),
})
} else if is(cmd::CONFIG) {
if rest.len() < 3 {
crate::usage!("config <part> <field> <value>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Config {
part: rest[0].clone(),
field: rest[1].clone(),
value: rest[2].clone(),
})
} else if is(cmd::CLEAR) {
ParseResult::Matched(SubCmd::Clear)
} else if is(cmd::REPORT) {
ParseResult::Matched(SubCmd::Report {
content: rest.to_vec(),
})
} else if is(cmd::REPORTCTL) {
if rest.is_empty() {
crate::usage!("reportctl <new|sync|push|pull|set-url> [date|message|url]");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Reportctl {
action: rest[0].clone(),
arg: rest.get(1).cloned(),
})
} else if is(cmd::CHECK) {
ParseResult::Matched(SubCmd::Check {
line_count: rest.first().cloned(),
})
} else if is(cmd::SEARCH) {
if rest.len() < 2 {
crate::usage!("search <line_count|all> <target> [-f|-fuzzy]");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Search {
line_count: rest[0].clone(),
target: rest[1].clone(),
fuzzy: rest.get(2).cloned(),
})
} else if is(cmd::TODO) {
ParseResult::Matched(SubCmd::Todo {
content: rest.to_vec(),
})
} else if is(cmd::CHAT) {
let mut cont = false;
let mut session: Option<String> = None;
let mut remote = false;
let mut port: u16 = 9390;
let mut content: Vec<String> = Vec::new();
let mut i = 0;
while i < rest.len() {
match rest[i].as_str() {
"--continue" | "-c" => {
cont = true;
i += 1;
}
"--session" => {
i += 1;
if i < rest.len() {
session = Some(rest[i].clone());
i += 1;
}
}
"--remote" => {
remote = true;
i += 1;
}
"--port" => {
i += 1;
if i < rest.len() {
port = rest[i].parse().unwrap_or(9390);
i += 1;
}
}
_ => {
content.push(rest[i].clone());
i += 1;
}
}
}
ParseResult::Matched(SubCmd::Chat {
cont,
session,
content,
remote,
port,
})
} else if is(cmd::SCRIPT) {
if rest.is_empty() {
crate::usage!("script <script_name> [\"<script_content>\"]");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Script {
name: rest[0].clone(),
content: if rest.len() > 1 {
rest[1..].to_vec()
} else {
vec![]
},
})
} else if is(cmd::TIME) {
if rest.len() < 2 {
crate::usage!("time countdown <duration>");
return ParseResult::Handled;
}
ParseResult::Matched(SubCmd::Time {
function: rest[0].clone(),
arg: rest[1].clone(),
})
} else if is(cmd::VERSION) {
ParseResult::Matched(SubCmd::Version)
} else if is(cmd::HELP) {
ParseResult::Matched(SubCmd::Help)
} else if is(cmd::COMPLETION) {
ParseResult::Matched(SubCmd::Completion {
shell: rest.first().cloned(),
})
} else if is(cmd::UPDATE) {
ParseResult::Matched(SubCmd::Update {
check: rest
.first()
.map(|s| s == "--check" || s == "-c")
.unwrap_or(false),
interactive: true,
})
} else if is(cmd::MD) {
ParseResult::Matched(SubCmd::Md {
args: rest.to_vec(),
})
} else if is(cmd::NOTEBOOK) {
ParseResult::Matched(SubCmd::Notebook {
args: rest.to_vec(),
})
} else {
ParseResult::NotFound
}
}