Start replacing `clap` with `oof`
[ouch.git] / oof / src / flags.rs
blob571713cf50647dda09c85592ad51e2490fdc9df2
1 use std::{
2     collections::{BTreeMap, BTreeSet},
3     ffi::{OsStr, OsString},
4 };
6 /// Shallow type, created to indicate a `Flag` that accepts a argument.
7 ///
8 /// ArgFlag::long(), is actually a Flag::long(), but sets a internal attribute.
9 ///
10 /// Examples in here pls
11 #[derive(Debug)]
12 pub struct ArgFlag;
14 impl ArgFlag {
15     pub fn long(name: &'static str) -> Flag {
16         Flag {
17             long: name,
18             short: None,
19             takes_value: true,
20         }
21     }
24 #[derive(Debug, PartialEq, Clone)]
25 pub struct Flag {
26     // Also the name
27     pub long: &'static str,
28     pub short: Option<char>,
29     pub takes_value: bool,
32 impl Flag {
33     pub fn long(name: &'static str) -> Self {
34         Self {
35             long: name,
36             short: None,
37             takes_value: false,
38         }
39     }
41     pub fn short(mut self, short_flag_char: char) -> Self {
42         self.short = Some(short_flag_char);
43         self
44     }
47 #[derive(Default, PartialEq, Eq, Debug)]
48 pub struct Flags {
49     pub boolean_flags: BTreeSet<&'static str>,
50     pub argument_flags: BTreeMap<&'static str, OsString>,
53 impl Flags {
54     pub fn new() -> Self {
55         Self::default()
56     }
59 impl Flags {
60     pub fn is_present(&self, flag_name: &str) -> bool {
61         self.boolean_flags.contains(flag_name) || self.argument_flags.contains_key(flag_name)
62     }
64     pub fn arg(&self, flag_name: &str) -> Option<&OsString> {
65         self.argument_flags.get(flag_name)
66     }
68     pub fn take_arg(&mut self, flag_name: &str) -> Option<OsString> {
69         self.argument_flags.remove(flag_name)
70     }
73 #[derive(Debug)]
74 pub enum FlagType {
75     None,
76     Short,
77     Long,
80 impl FlagType {
81     pub fn from(text: impl AsRef<OsStr>) -> Self {
82         let text = text.as_ref();
84         let mut iter;
86         #[cfg(target_family = "unix")]
87         {
88             use std::os::unix::ffi::OsStrExt;
89             iter = text.as_bytes().iter();
90         }
91         #[cfg(target_family = "windows")]
92         {
93             use std::os::windows::ffi::OsStrExt;
94             iter = text.encode_wide
95         }
97         // 45 is the code for a hyphen
98         // Typed as 45_u16 for Windows
99         // Typed as 45_u8 for Unix
100         if let Some(45) = iter.next() {
101             if let Some(45) = iter.next() {
102                 Self::Long
103             } else {
104                 Self::Short
105             }
106         } else {
107             Self::None
108         }
109     }