tome-scripts 0.12.2

Turn directories of shell scripts into full-blown CLIs
Documentation
use super::super::{
    directory, script,
    types::CommandType,
};
use super::builtins::BUILTIN_COMMANDS;
use std::{fs, io, path::PathBuf};

pub fn complete(
    command_directory_path: &str,
    shell: &str,
    args: &[String],
) -> Result<String, String> {
    let mut target = PathBuf::from(&command_directory_path);
    let mut is_file = false;
    let mut args_peekable = args.iter().peekable();
    if let Some(subcommand) = args_peekable.peek() {
        if BUILTIN_COMMANDS.get(*subcommand).is_some() {
            return Ok(String::new());
        }
    }
    while let Some(arg) = args_peekable.peek() {
        target.push(arg);
        if let Some(resolved) = script::resolve_source_path(&target) {
            target = resolved;
            is_file = true;
            args_peekable.next();
            break;
        } else if target.is_dir() {
            args_peekable.next();
        } else {
            target.pop();
            break;
        }
    }
    let remaining_args: Vec<_> = args_peekable.collect();
    return match is_file {
        false => {
            let ignorer = directory::TomeIgnorer::new(std::path::Path::new(command_directory_path));
            let paths_raw: io::Result<_> = fs::read_dir(target.to_str().unwrap());
            let mut paths: Vec<_> = match paths_raw {
                Err(_a) => return Err("Invalid argument to completion".to_string()),
                Ok(a) => a,
            }
            .filter_map(|r| match r {
                Ok(path_buf) => {
                    let path = path_buf.path();
                    if ignorer.is_ignored(&path) {
                        return None;
                    }
                    if path.is_file() && !script::is_tome_script(&path) {
                        return None;
                    }
                    let name = path.file_name().unwrap().to_str().unwrap_or("").to_owned();
                    Some(script::strip_source_suffix(&name).to_owned())
                }
                Err(_) => None,
            })
            .collect();
            if target.to_str().unwrap() == command_directory_path {
                for command in BUILTIN_COMMANDS.keys() {
                    paths.push(command.to_owned());
                }
            }
            paths.sort_by_key(|f| f.to_owned());
            Ok(paths.join(" "))
        }
        true => match script::Script::load(target.to_str().unwrap_or_default()) {
            Ok(script) => {
                script.get_execution_body(CommandType::Completion, shell, &remaining_args)
            }
            Err(error) => return Err(format!("IOError loading file: {:?}", error)),
        },
    };
}