use std::{fmt, str};
use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[allow(dead_code)]
pub enum PlatformType {
Linux,
OsX,
Windows,
SunOs,
Android,
FreeBsd,
NetBsd,
OpenBsd,
Common,
}
impl fmt::Display for PlatformType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Linux => write!(f, "Linux"),
Self::OsX => write!(f, "macOS / BSD"),
Self::Windows => write!(f, "Windows"),
Self::SunOs => write!(f, "SunOS"),
Self::Android => write!(f, "Android"),
Self::FreeBsd => write!(f, "FreeBSD"),
Self::NetBsd => write!(f, "NetBSD"),
Self::OpenBsd => write!(f, "OpenBSD"),
Self::Common => write!(f, "Common"),
}
}
}
impl clap::ValueEnum for PlatformType {
fn value_variants<'a>() -> &'a [Self] {
&[
Self::Linux,
Self::OsX,
Self::SunOs,
Self::Windows,
Self::Android,
Self::FreeBsd,
Self::NetBsd,
Self::OpenBsd,
Self::Common,
]
}
fn to_possible_value<'a>(&self) -> Option<clap::builder::PossibleValue> {
match self {
Self::Linux => Some(clap::builder::PossibleValue::new("linux")),
Self::OsX => Some(clap::builder::PossibleValue::new("macos").alias("osx")),
Self::Windows => Some(clap::builder::PossibleValue::new("windows")),
Self::SunOs => Some(clap::builder::PossibleValue::new("sunos")),
Self::Android => Some(clap::builder::PossibleValue::new("android")),
Self::FreeBsd => Some(clap::builder::PossibleValue::new("freebsd")),
Self::NetBsd => Some(clap::builder::PossibleValue::new("netbsd")),
Self::OpenBsd => Some(clap::builder::PossibleValue::new("openbsd")),
Self::Common => Some(clap::builder::PossibleValue::new("common")),
}
}
}
impl PlatformType {
#[cfg(target_os = "linux")]
pub fn current() -> Self {
Self::Linux
}
#[cfg(any(target_os = "macos", target_os = "dragonfly"))]
pub fn current() -> Self {
Self::OsX
}
#[cfg(target_os = "windows")]
pub fn current() -> Self {
Self::Windows
}
#[cfg(target_os = "android")]
pub fn current() -> Self {
Self::Android
}
#[cfg(target_os = "freebsd")]
pub fn current() -> Self {
Self::FreeBsd
}
#[cfg(target_os = "netbsd")]
pub fn current() -> Self {
Self::NetBsd
}
#[cfg(target_os = "openbsd")]
pub fn current() -> Self {
Self::OpenBsd
}
#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "dragonfly",
target_os = "windows",
target_os = "android",
)))]
pub fn current() -> Self {
Self::Other
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, Deserialize, clap::ValueEnum)]
#[serde(rename_all = "lowercase")]
#[derive(Default)]
pub enum ColorOptions {
Always,
#[default]
Auto,
Never,
}
#[derive(Debug, Eq, PartialEq)]
pub enum LineType {
Empty,
Title(String),
Description(String),
ExampleText(String),
ExampleCode(String),
Other(String),
}
impl<'a> From<&'a str> for LineType {
fn from(line: &'a str) -> Self {
let trimmed: &str = line.trim_end();
let mut chars = trimmed.chars();
match chars.next() {
None => Self::Empty,
Some('#') => Self::Title(
trimmed
.trim_start_matches(|chr: char| chr == '#' || chr.is_whitespace())
.into(),
),
Some('>') => Self::Description(
trimmed
.trim_start_matches(|chr: char| chr == '>' || chr.is_whitespace())
.into(),
),
Some(' ') => Self::ExampleCode(trimmed.trim_start_matches(char::is_whitespace).into()),
Some(_) => Self::ExampleText(trimmed.into()),
}
}
}
impl LineType {
pub fn from_v1(line: &str) -> Self {
let trimmed = line.trim();
let mut chars = trimmed.chars();
match chars.next() {
None => Self::Empty,
Some('#') => Self::Title(
trimmed
.trim_start_matches(|chr: char| chr == '#' || chr.is_whitespace())
.into(),
),
Some('>') => Self::Description(
trimmed
.trim_start_matches(|chr: char| chr == '>' || chr.is_whitespace())
.into(),
),
Some('-') => Self::ExampleText(
trimmed
.trim_start_matches(|chr: char| chr == '-' || chr.is_whitespace())
.into(),
),
Some('`') if chars.last() == Some('`') => Self::ExampleCode(
trimmed
.trim_matches(|chr: char| chr == '`' || chr.is_whitespace())
.into(),
),
Some(_) => Self::Other(trimmed.into()),
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum PathSource {
OsConvention,
EnvVar,
ConfigFile,
Cli,
}
impl fmt::Display for PathSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::OsConvention => "OS convention",
Self::EnvVar => "env variable",
Self::ConfigFile => "config file",
Self::Cli => "command line argument",
}
)
}
}
#[cfg(test)]
mod test {
use super::LineType;
#[test]
fn test_linetype_from_str() {
assert_eq!(LineType::from(""), LineType::Empty);
assert_eq!(LineType::from(" \n \r"), LineType::Empty);
assert_eq!(
LineType::from("# Hello there"),
LineType::Title("Hello there".into())
);
assert_eq!(
LineType::from("> tis a description \n"),
LineType::Description("tis a description".into())
);
assert_eq!(
LineType::from("some command "),
LineType::ExampleText("some command".into())
);
assert_eq!(
LineType::from(" $ cargo run "),
LineType::ExampleCode("$ cargo run".into())
);
}
}