use super::Text;
use crate::model::{RepoLink, not_a_link, parse_links};
use anyhow::{Result, anyhow, bail};
pub(super) fn search_words(mut words: Vec<String>) -> String {
drop_options_end(&mut words);
words.join(" ")
}
fn drop_options_end(words: &mut Vec<String>) {
if let Some(at) = words.iter().position(|w| w == "--") {
words.remove(at);
}
}
pub(super) fn typed_links(value: &str) -> Result<(Vec<u32>, Vec<RepoLink>)> {
if let Some(word) = not_a_link(value) {
bail!("`{word}` isn't an entry id (12 or #12) or another repository's entry (REPO#ID)");
}
Ok(parse_links(value))
}
pub(super) fn new_title(words: Vec<String>) -> Result<String> {
let mut title = Vec::new();
let mut words = words.into_iter();
while let Some(word) = words.next() {
match word.as_str() {
"--" => title.extend(words.by_ref()),
other if other.starts_with("--") => bail!("unknown rename option `{other}`"),
_ => title.push(word),
}
}
let title = title.join(" ");
if title.trim().is_empty() {
bail!("rename needs the new title");
}
Ok(title)
}
pub(super) fn first_id(args: &mut Vec<String>) -> Result<u32> {
if args.is_empty() {
bail!("an entry id is needed");
}
let arg = args.remove(0);
arg.trim_start_matches('#').parse().map_err(|_| anyhow!("`{arg}` isn't an entry id"))
}
pub(super) fn id_and_text(args: &mut Vec<String>, needs: &str) -> Result<(u32, Text)> {
let id = first_id(args)?;
Ok((id, rest_as_text(args, needs)?))
}
pub(super) fn rest_as_text(args: &mut Vec<String>, needs: &str) -> Result<Text> {
let mut words = std::mem::take(args);
drop_options_end(&mut words);
match words.as_slice() {
[] => bail!("{needs}: TEXT, or - to read it from stdin"),
[dash] if dash == "-" => Ok(Text::Stdin),
_ => Ok(Text::Given(words.join(" "))),
}
}