Switch from BTree to Hash collections
[ouch.git] / src / oof / flags.rs
blob231ec5cb967beb1c5b8eb23205bcfda921ff55a8
1 use std::{
2     collections::{HashMap, HashSet},
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 { long: name, short: None, takes_value: true }
17     }
20 #[derive(Debug, PartialEq, Clone)]
21 pub struct Flag {
22     // Also the name
23     pub long: &'static str,
24     pub short: Option<char>,
25     pub takes_value: bool,
28 impl std::fmt::Display for Flag {
29     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30         match self.short {
31             Some(short_flag) => write!(f, "-{}/--{}", short_flag, self.long),
32             None => write!(f, "--{}", self.long),
33         }
34     }
37 impl Flag {
38     pub fn long(name: &'static str) -> Self {
39         Self { long: name, short: None, takes_value: false }
40     }
42     pub fn short(mut self, short_flag_char: char) -> Self {
43         self.short = Some(short_flag_char);
44         self
45     }
48 #[derive(Default, PartialEq, Eq, Debug)]
49 pub struct Flags {
50     pub boolean_flags: HashSet<&'static str>,
51     pub argument_flags: HashMap<&'static str, OsString>,
54 impl Flags {
55     pub fn new() -> Self {
56         Self::default()
57     }
59     pub fn is_present(&self, flag_name: &str) -> bool {
60         self.boolean_flags.contains(flag_name) || self.argument_flags.contains_key(flag_name)
61     }
63     pub fn arg(&self, flag_name: &str) -> Option<&OsString> {
64         self.argument_flags.get(flag_name)
65     }
67     pub fn take_arg(&mut self, flag_name: &str) -> Option<OsString> {
68         self.argument_flags.remove(flag_name)
69     }
72 #[derive(Debug)]
73 pub enum FlagType {
74     None,
75     Short,
76     Long,
79 impl FlagType {
80     pub fn from(text: impl AsRef<OsStr>) -> Self {
81         let text = text.as_ref();
83         let mut iter;
85         #[cfg(target_family = "unix")]
86         {
87             use std::os::unix::ffi::OsStrExt;
88             iter = text.as_bytes().iter();
89         }
90         #[cfg(target_family = "windows")]
91         {
92             use std::os::windows::ffi::OsStrExt;
93             iter = text.encode_wide();
94         }
96         // 45 is the code for a hyphen
97         // Typed as 45_u16 for Windows
98         // Typed as 45_u8 for Unix
99         if let Some(45) = iter.next() {
100             if let Some(45) = iter.next() {
101                 Self::Long
102             } else {
103                 Self::Short
104             }
105         } else {
106             Self::None
107         }
108     }