1use std::fmt;
4use std::fmt::Write as _;
5
6use crate::actions::ApplyResult;
7use crate::Parse;
8
9#[derive(Debug, Clone)]
19pub enum Flag<'a> {
20 Short(&'a str),
22 Long(&'a str),
24 LongShort(&'a str, &'a str),
26 Many(Box<[Flag<'a>]>),
28}
29
30impl Flag<'_> {
31 pub fn first_to_string(&self) -> String {
33 match self {
34 &Flag::Short(s) => format!("-{}", s),
35 &Flag::Long(l) => format!("--{}", l),
36 &Flag::LongShort(l, _) => format!("--{}", l),
37 Flag::Many(v) => v[0].first_to_string(),
38 }
39 }
40
41 pub fn from_input<'a, P: Parse>(input: &mut P, context: &Flag<'a>) -> ApplyResult {
43 Ok(match context {
44 Flag::Short(f) => input.parse_short_flag(f),
45 Flag::Long(f) => input.parse_long_flag(f),
46 Flag::LongShort(l, s) => {
47 input.parse_long_flag(l) || input.parse_short_flag(s)
48 }
49 Flag::Many(flags) => {
50 flags.iter().any(|flag| Self::from_input(input, flag).is_ok())
51 }
52 })
53 }
54}
55
56impl fmt::Display for Flag<'_> {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 Flag::Short(s) => write!(f, "-{}", s),
60 Flag::Long(l) => write!(f, "--{}", l),
61 Flag::LongShort(l, s) => write!(f, "--{},-{}", l, s),
62 Flag::Many(v) => {
63 for (i, flag) in v.iter().enumerate() {
64 if i > 0 {
65 f.write_char(',')?;
66 }
67 fmt::Display::fmt(flag, f)?;
68 }
69 Ok(())
70 }
71 }
72 }
73}
74
75#[derive(Debug, Clone)]
77pub struct ArgCtx<'a, C> {
78 pub flag: Flag<'a>,
80 pub inner: C,
82}
83
84impl<'a, C> ArgCtx<'a, C> {
85 pub fn new(flag: Flag<'a>, inner: C) -> Self {
87 Self { flag, inner }
88 }
89}
90
91impl<'a, C: Default> From<Flag<'a>> for ArgCtx<'a, C> {
92 fn from(flag: Flag<'a>) -> Self {
93 ArgCtx { flag, inner: C::default() }
94 }
95}
96
97#[derive(Debug, Clone)]
99pub struct PosCtx<'a, C> {
100 pub name: &'a str,
102 pub inner: C,
104}
105
106impl<'a, C> PosCtx<'a, C> {
107 pub fn new(name: &'a str, inner: C) -> Self {
109 Self { name, inner }
110 }
111}
112
113impl<'a, C: Default> From<&'a str> for PosCtx<'a, C> {
114 fn from(name: &'a str) -> Self {
115 PosCtx { name, inner: C::default() }
116 }
117}