use std::path::Path;
use serde::Deserialize;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PathType {
Directory,
File,
Existent,
}
impl PathType {
pub fn parse(s: &str) -> Result<Self, String> {
match s {
"directory" | "dir" | "d" => Ok(Self::Directory),
"file" | "f" => Ok(Self::File),
"existent" | "exist" | "e" => Ok(Self::Existent),
_ => Err(format!("invalid type {s:?}")),
}
}
pub fn name(self) -> &'static str {
match self {
Self::Directory => "directory",
Self::File => "file",
Self::Existent => "existent",
}
}
pub fn matches(self, path: &Path) -> bool {
match self {
Self::Directory => path.is_dir(),
Self::File => path.is_file(),
Self::Existent => path.exists(),
}
}
pub fn infer(path: &str) -> Self {
if path.ends_with('/') {
Self::Directory
} else {
Self::Existent
}
}
}
#[derive(Clone, Copy, Debug, clap::ValueEnum)]
pub enum Format {
Tsv,
Json,
}
#[derive(Clone, Copy, Debug, clap::ValueEnum)]
pub enum SortBy {
Abbr,
Path,
}
#[derive(Clone, Copy, Debug, clap::ValueEnum)]
pub enum CacheTarget {
Shell,
}
impl SortBy {
pub fn field(self) -> &'static str {
match self {
Self::Abbr => "abbr",
Self::Path => "path",
}
}
}
#[derive(Debug, Deserialize)]
pub struct RawDef {
pub abbr: String,
pub path: String,
#[serde(default)]
pub desc: Option<String>,
#[serde(default, rename = "type")]
pub type_: Option<String>,
}
#[derive(Debug, Default, Deserialize)]
pub struct DefFile {
#[serde(default)]
pub vars: toml::Table,
#[serde(default, rename = "path")]
pub paths: Vec<RawDef>,
}
#[derive(Debug)]
pub struct Entry {
pub abbr: String,
pub desc: Option<String>,
pub expanded: String,
pub type_: PathType,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn type_aliases() {
for s in ["directory", "dir", "d"] {
assert_eq!(PathType::parse(s), Ok(PathType::Directory));
}
for s in ["file", "f"] {
assert_eq!(PathType::parse(s), Ok(PathType::File));
}
for s in ["existent", "exist", "e"] {
assert_eq!(PathType::parse(s), Ok(PathType::Existent));
}
assert!(PathType::parse("dirs").is_err());
}
#[test]
fn type_inference() {
assert_eq!(PathType::infer("~/src/"), PathType::Directory);
assert_eq!(PathType::infer("~/init.el"), PathType::Existent);
}
}