aopt_core/opt/
action.rs

1use std::ffi::OsStr;
2use std::ffi::OsString;
3
4use crate::map::ErasedTy;
5use crate::value::AnyValue;
6
7/// The default action type for option value saving, see [`process`](https://docs.rs/aopt/latest/aopt/opt/enum.Action.html#method.process).
8#[non_exhaustive]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
11pub enum Action {
12    /// Set and replace current value of [`AnyValue`]
13    Set,
14
15    /// Append value into [`AnyValue`]
16    App,
17
18    /// Pop value from [`AnyValue`]
19    Pop,
20
21    /// Saving the count of arguments into [`AnyValue`]
22    Cnt,
23
24    /// Clear the value of [`AnyValue`]
25    Clr,
26
27    /// Do nothing
28    #[default]
29    Null,
30}
31
32impl Action {
33    pub fn is_set(&self) -> bool {
34        matches!(self, Self::Set)
35    }
36
37    pub fn is_app(&self) -> bool {
38        matches!(self, Self::App)
39    }
40
41    pub fn is_pop(&self) -> bool {
42        matches!(self, Self::Pop)
43    }
44
45    pub fn is_cnt(&self) -> bool {
46        matches!(self, Self::Cnt)
47    }
48
49    pub fn is_clr(&self) -> bool {
50        matches!(self, Self::Clr)
51    }
52
53    pub fn is_null(&self) -> bool {
54        matches!(self, Self::Null)
55    }
56
57    /// Save the value in [`handler`](AnyValue).
58    pub fn store1<U: ErasedTy>(&self, val: Option<U>, handler: &mut AnyValue) -> bool {
59        crate::trace!(
60            "saving value {:?}({:?}) [ty = {}] = {:?} in store1",
61            val,
62            self,
63            std::any::type_name::<U>(),
64            crate::typeid::<Vec<U>>()
65        );
66        if let Some(val) = val {
67            match self {
68                Action::Set => {
69                    handler.set(vec![val]);
70                }
71                Action::App => {
72                    handler.push(val);
73                }
74                Action::Pop => {
75                    handler.pop::<U>();
76                }
77                Action::Cnt => {
78                    handler.entry::<u64>().or_insert(vec![0])[0] += 1;
79                }
80                Action::Clr => {
81                    handler.remove::<U>();
82                }
83                Action::Null => {
84                    // NOTHING
85                }
86            }
87            crate::trace!("after saving handler: {:?}", handler);
88            true
89        } else {
90            false
91        }
92    }
93
94    /// Save the value in [`handler`](AnyValue) and raw value in `raw_handler`.
95    pub fn store2<U: ErasedTy>(
96        &self,
97        raw: Option<&OsStr>,
98        val: Option<U>,
99        raw_handler: &mut Vec<OsString>,
100        handler: &mut AnyValue,
101    ) -> bool {
102        let ret = self.store1(val, handler);
103
104        if ret {
105            if let Some(raw) = raw {
106                raw_handler.push(raw.to_os_string());
107            }
108        }
109        ret
110    }
111}
112
113impl std::fmt::Display for Action {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        match self {
116            Action::Set => {
117                write!(f, "Action::Set")
118            }
119            Action::App => {
120                write!(f, "Action::App")
121            }
122            Action::Pop => {
123                write!(f, "Action::Pop")
124            }
125            Action::Cnt => {
126                write!(f, "Action::Cnt")
127            }
128            Action::Clr => {
129                write!(f, "Action::Clr")
130            }
131            Action::Null => {
132                write!(f, "Action::Null")
133            }
134        }
135    }
136}