use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArgType {
String,
Int,
Float,
Bool,
}
impl ArgType {
pub const fn type_name(&self) -> &'static str {
match self {
ArgType::String => "字符串",
ArgType::Int => "整数",
ArgType::Float => "浮点数",
ArgType::Bool => "布尔值",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ArgMode {
#[default]
Positional,
Named,
}
#[derive(Debug, Clone)]
pub struct Arg {
pub name: &'static str,
pub arg_type: ArgType,
pub mode: ArgMode,
pub required: bool,
pub default: Option<ArgValue>,
pub description: Option<&'static str>,
}
impl Default for Arg {
fn default() -> Self {
Self {
name: "",
arg_type: ArgType::String,
mode: ArgMode::Positional,
required: false,
default: None,
description: None,
}
}
}
impl Arg {
pub fn new(name: &'static str) -> Self {
Self { name, ..Default::default() }
}
pub fn string(name: &'static str) -> Self {
Self::new(name).with_type(ArgType::String)
}
pub fn int(name: &'static str) -> Self {
Self::new(name).with_type(ArgType::Int)
}
pub fn float(name: &'static str) -> Self {
Self::new(name).with_type(ArgType::Float)
}
pub fn bool(name: &'static str) -> Self {
Self::new(name).with_type(ArgType::Bool)
}
pub fn with_type(mut self, arg_type: ArgType) -> Self {
self.arg_type = arg_type;
self
}
pub fn required(mut self) -> Self {
self.required = true;
self
}
pub fn optional(mut self) -> Self {
self.required = false;
self
}
pub fn default_value(mut self, value: ArgValue) -> Self {
self.default = Some(value);
self
}
pub fn description(mut self, desc: &'static str) -> Self {
self.description = Some(desc);
self
}
pub fn positional(mut self) -> Self {
self.mode = ArgMode::Positional;
self
}
pub fn named(mut self) -> Self {
self.mode = ArgMode::Named;
self
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ArgValue {
String(String),
Int(i64),
Float(f64),
Bool(bool),
}
impl ArgValue {
pub fn as_str(&self) -> Option<&str> {
match self {
ArgValue::String(s) => Some(s),
_ => None,
}
}
pub fn as_int(&self) -> Option<i64> {
match self {
ArgValue::Int(i) => Some(*i),
_ => None,
}
}
pub fn as_float(&self) -> Option<f64> {
match self {
ArgValue::Float(f) => Some(*f),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match self {
ArgValue::Bool(b) => Some(*b),
_ => None,
}
}
}
impl fmt::Display for ArgValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ArgValue::String(s) => write!(f, "{}", s),
ArgValue::Int(i) => write!(f, "{}", i),
ArgValue::Float(fl) => write!(f, "{}", fl),
ArgValue::Bool(b) => write!(f, "{}", b),
}
}
}
impl From<String> for ArgValue {
fn from(s: String) -> Self {
ArgValue::String(s)
}
}
impl From<&str> for ArgValue {
fn from(s: &str) -> Self {
ArgValue::String(s.to_string())
}
}
impl From<i64> for ArgValue {
fn from(i: i64) -> Self {
ArgValue::Int(i)
}
}
impl From<f64> for ArgValue {
fn from(f: f64) -> Self {
ArgValue::Float(f)
}
}
impl From<bool> for ArgValue {
fn from(b: bool) -> Self {
ArgValue::Bool(b)
}
}