aopt/parser/
returnval.rs

1use std::ffi::OsString;
2
3use crate::args::Args;
4use crate::ctx::Ctx;
5use crate::opt::Style;
6use crate::{Error, Uid};
7
8#[derive(Debug, Clone, Default)]
9pub struct Guess {
10    pub uid: Uid,
11
12    pub name: Option<String>,
13
14    pub style: Style,
15
16    pub arg: Option<OsString>,
17
18    pub index: usize,
19
20    pub total: usize,
21}
22
23#[derive(Debug, Clone, Default)]
24pub struct Context {
25    pub orig: Args,
26
27    pub args: Vec<OsString>,
28
29    pub guess: Option<Guess>,
30}
31
32/// Return value for [`Policy`](crate::parser::Policy).
33#[derive(Debug, Clone, Default)]
34pub struct Return {
35    ctx: Context,
36
37    failure: Option<Error>,
38}
39
40impl Return {
41    pub fn new(ctx: Ctx<'_>) -> Self {
42        let args = ctx.args.into_iter().map(|v| v.to_os_string()).collect();
43
44        Self {
45            ctx: Context {
46                orig: ctx.orig,
47                args,
48                guess: ctx.inner_ctx.map(|v| Guess {
49                    uid: v.uid(),
50                    name: v.name().map(|v| v.to_string()),
51                    style: v.style(),
52                    arg: v.arg().map(|v| v.to_os_string()),
53                    index: v.idx(),
54                    total: v.total(),
55                }),
56            },
57            failure: None,
58        }
59    }
60
61    pub fn with_failure(mut self, failure: Error) -> Self {
62        self.failure = Some(failure);
63        self
64    }
65
66    pub fn set_failure(&mut self, failure: Error) -> &mut Self {
67        self.failure = Some(failure);
68        self
69    }
70
71    pub fn failure(&self) -> Option<&Error> {
72        self.failure.as_ref()
73    }
74
75    pub fn ctx(&self) -> &Context {
76        &self.ctx
77    }
78
79    pub fn args(&self) -> &[OsString] {
80        &self.ctx.args
81    }
82
83    /// The original arguments passed by user.
84    pub fn orig_args(&self) -> &Args {
85        &self.ctx.orig
86    }
87
88    /// The [`status`](Return::status) is true if parsing successes
89    /// otherwise it will be false if any [`failure`](Error::is_failure) raised.
90    pub fn status(&self) -> bool {
91        self.failure.is_none()
92    }
93
94    /// Unwrap the [`Ctx`] from [`Return`].
95    pub fn unwrap(self) -> Context {
96        Result::unwrap(if self.failure.is_none() {
97            Ok(self.ctx)
98        } else {
99            Err(self.failure)
100        })
101    }
102
103    pub fn ok(self) -> Result<Context, Error> {
104        if let Some(failure) = self.failure {
105            Err(failure)
106        } else {
107            Ok(self.ctx)
108        }
109    }
110
111    pub fn take_ctx(&mut self) -> Context {
112        std::mem::take(&mut self.ctx)
113    }
114
115    pub fn take_failure(&mut self) -> Option<Error> {
116        self.failure.take()
117    }
118
119    pub fn take_args(&mut self) -> Vec<OsString> {
120        std::mem::take(&mut self.ctx.args)
121    }
122
123    pub fn clone_args(&self) -> Vec<OsString> {
124        self.ctx.args.clone()
125    }
126}
127
128impl From<Return> for bool {
129    fn from(value: Return) -> Self {
130        value.status()
131    }
132}
133
134impl From<&Return> for bool {
135    fn from(value: &Return) -> Self {
136        value.status()
137    }
138}
139
140impl From<&mut Return> for bool {
141    fn from(value: &mut Return) -> Self {
142        value.status()
143    }
144}
145
146impl From<Return> for Args {
147    fn from(mut value: Return) -> Self {
148        Self::new(value.take_args().into_iter())
149    }
150}
151
152impl From<&Return> for Args {
153    fn from(value: &Return) -> Self {
154        Self::new(value.clone_args().into_iter())
155    }
156}
157
158impl From<&mut Return> for Args {
159    fn from(value: &mut Return) -> Self {
160        Self::new(value.take_args().into_iter())
161    }
162}