Skip to content

Commit 17a07ab

Browse files
committed
refactor: Remove lifetime from ArgPredicate
1 parent 30d4ef4 commit 17a07ab

File tree

11 files changed

+225
-16
lines changed

11 files changed

+225
-16
lines changed

Diff for: src/builder/arg.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub struct Arg<'help> {
5959
pub(crate) settings: ArgFlags,
6060
pub(crate) overrides: Vec<Id>,
6161
pub(crate) groups: Vec<Id>,
62-
pub(crate) requires: Vec<(ArgPredicate<'help>, Id)>,
62+
pub(crate) requires: Vec<(ArgPredicate, Id)>,
6363
pub(crate) r_ifs: Vec<(Id, OsString)>,
6464
pub(crate) r_ifs_all: Vec<(Id, OsString)>,
6565
pub(crate) r_unless: Vec<Id>,
@@ -73,7 +73,7 @@ pub struct Arg<'help> {
7373
pub(crate) num_vals: Option<ValueRange>,
7474
pub(crate) val_delim: Option<char>,
7575
pub(crate) default_vals: Vec<&'help OsStr>,
76-
pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate<'help>, Option<&'help OsStr>)>,
76+
pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate, Option<&'help OsStr>)>,
7777
pub(crate) default_missing_vals: Vec<&'help OsStr>,
7878
#[cfg(feature = "env")]
7979
pub(crate) env: Option<(&'help OsStr, Option<OsString>)>,
@@ -3266,7 +3266,7 @@ impl<'help> Arg<'help> {
32663266
#[must_use]
32673267
pub fn requires_if(mut self, val: &'help str, arg_id: impl Into<Id>) -> Self {
32683268
self.requires
3269-
.push((ArgPredicate::Equals(OsStr::new(val)), arg_id.into()));
3269+
.push((ArgPredicate::Equals(val.to_owned().into()), arg_id.into()));
32703270
self
32713271
}
32723272

@@ -3321,7 +3321,7 @@ impl<'help> Arg<'help> {
33213321
) -> Self {
33223322
self.requires.extend(
33233323
ifs.into_iter()
3324-
.map(|(val, arg)| (ArgPredicate::Equals(OsStr::new(val)), arg.into())),
3324+
.map(|(val, arg)| (ArgPredicate::Equals(val.to_owned().into()), arg.into())),
33253325
);
33263326
self
33273327
}

Diff for: src/builder/arg_predicate.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
use crate::OsStr;
2+
13
#[derive(Clone, Debug, PartialEq, Eq)]
2-
pub(crate) enum ArgPredicate<'help> {
4+
pub(crate) enum ArgPredicate {
35
IsPresent,
4-
Equals(&'help std::ffi::OsStr),
6+
Equals(OsStr),
57
}
68

7-
impl<'help> From<Option<&'help std::ffi::OsStr>> for ArgPredicate<'help> {
9+
impl<'help> From<Option<&'help std::ffi::OsStr>> for ArgPredicate {
810
fn from(other: Option<&'help std::ffi::OsStr>) -> Self {
911
match other {
10-
Some(other) => Self::Equals(other),
12+
Some(other) => Self::Equals(other.to_owned().into()),
1113
None => Self::IsPresent,
1214
}
1315
}

Diff for: src/builder/command.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4333,7 +4333,7 @@ impl<'help> Command<'help> {
43334333

43344334
pub(crate) fn unroll_arg_requires<F>(&self, func: F, arg: &Id) -> Vec<Id>
43354335
where
4336-
F: Fn(&(ArgPredicate<'_>, Id)) -> Option<Id>,
4336+
F: Fn(&(ArgPredicate, Id)) -> Option<Id>,
43374337
{
43384338
let mut processed = vec![];
43394339
let mut r_vec = vec![arg];

Diff for: src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub use crate::util::color::ColorChoice;
109109
#[allow(unused_imports)]
110110
pub(crate) use crate::util::color::ColorChoice;
111111
pub use crate::util::Id;
112+
pub(crate) use crate::util::OsStr;
112113
pub(crate) use crate::util::Str;
113114

114115
pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};

Diff for: src/output/usage.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ impl<'help, 'cmd> Usage<'help, 'cmd> {
359359
};
360360

361361
for a in required.iter() {
362-
let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option<Id> {
362+
let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option<Id> {
363363
let required = match val {
364364
ArgPredicate::Equals(_) => {
365365
if let Some(matcher) = matcher {

Diff for: src/parser/arg_matcher.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl ArgMatcher {
125125
self.matches.subcommand_name()
126126
}
127127

128-
pub(crate) fn check_explicit<'a>(&self, arg: &Id, predicate: &ArgPredicate<'a>) -> bool {
128+
pub(crate) fn check_explicit(&self, arg: &Id, predicate: &ArgPredicate) -> bool {
129129
self.get(arg).map_or(false, |a| a.check_explicit(predicate))
130130
}
131131

Diff for: src/parser/validator.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl<'help, 'cmd> Validator<'help, 'cmd> {
215215
{
216216
debug!("Validator::gather_requires:iter:{:?}", name);
217217
if let Some(arg) = self.cmd.find(name) {
218-
let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option<Id> {
218+
let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option<Id> {
219219
let required = matcher.check_explicit(&arg.id, val);
220220
required.then(|| req_arg.clone())
221221
};
@@ -281,15 +281,15 @@ impl<'help, 'cmd> Validator<'help, 'cmd> {
281281
// Validate the conditionally required args
282282
for a in self.cmd.get_arguments() {
283283
for (other, val) in &a.r_ifs {
284-
if matcher.check_explicit(other, &ArgPredicate::Equals(val.as_os_str()))
284+
if matcher.check_explicit(other, &ArgPredicate::Equals(val.into()))
285285
&& !matcher.check_explicit(&a.id, &ArgPredicate::IsPresent)
286286
{
287287
return self.missing_required_error(matcher, vec![a.id.clone()]);
288288
}
289289
}
290290

291291
let match_all = a.r_ifs_all.iter().all(|(other, val)| {
292-
matcher.check_explicit(other, &ArgPredicate::Equals(val.as_os_str()))
292+
matcher.check_explicit(other, &ArgPredicate::Equals(val.into()))
293293
});
294294
if match_all
295295
&& !a.r_ifs_all.is_empty()

Diff for: src/util/id.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl PartialEq<str> for Id {
100100
}
101101
}
102102

103-
impl<'s> PartialEq<&'s str> for Id {
103+
impl PartialEq<&'_ str> for Id {
104104
#[inline]
105105
fn eq(&self, other: &&str) -> bool {
106106
PartialEq::eq(self.as_str(), *other)

Diff for: src/util/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ mod flat_map;
44
mod flat_set;
55
mod graph;
66
mod id;
7+
mod os_str;
78
mod str;
89
mod str_to_bool;
910

1011
pub use self::id::Id;
12+
pub use self::os_str::OsStr;
1113
pub use self::str::Str;
1214

1315
pub(crate) use self::flat_map::Entry;

Diff for: src/util/os_str.rs

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/// A UTF-8-encoded fixed string
2+
#[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
3+
pub struct OsStr {
4+
name: Inner,
5+
}
6+
7+
impl OsStr {
8+
pub(crate) fn from_string(name: std::ffi::OsString) -> Self {
9+
Self {
10+
name: Inner::Owned(name.into_boxed_os_str()),
11+
}
12+
}
13+
14+
pub(crate) fn from_ref(name: &std::ffi::OsStr) -> Self {
15+
Self {
16+
name: Inner::Owned(Box::from(name)),
17+
}
18+
}
19+
20+
pub(crate) const fn from_static_ref(name: &'static std::ffi::OsStr) -> Self {
21+
Self {
22+
name: Inner::Static(name),
23+
}
24+
}
25+
26+
/// Get the raw string of the `OsStr`
27+
pub fn as_os_str(&self) -> &std::ffi::OsStr {
28+
self.name.as_os_str()
29+
}
30+
}
31+
32+
impl From<&'_ OsStr> for OsStr {
33+
fn from(id: &'_ OsStr) -> Self {
34+
id.clone()
35+
}
36+
}
37+
38+
impl From<std::ffi::OsString> for OsStr {
39+
fn from(name: std::ffi::OsString) -> Self {
40+
Self::from_string(name)
41+
}
42+
}
43+
44+
impl From<&'_ std::ffi::OsString> for OsStr {
45+
fn from(name: &'_ std::ffi::OsString) -> Self {
46+
Self::from_ref(name.as_os_str())
47+
}
48+
}
49+
50+
impl From<std::string::String> for OsStr {
51+
fn from(name: std::string::String) -> Self {
52+
Self::from_string(name.into())
53+
}
54+
}
55+
56+
impl From<&'_ std::string::String> for OsStr {
57+
fn from(name: &'_ std::string::String) -> Self {
58+
Self::from_ref(name.as_str().as_ref())
59+
}
60+
}
61+
62+
impl From<&'static std::ffi::OsStr> for OsStr {
63+
fn from(name: &'static std::ffi::OsStr) -> Self {
64+
Self::from_static_ref(name)
65+
}
66+
}
67+
68+
impl From<&'_ &'static std::ffi::OsStr> for OsStr {
69+
fn from(name: &'_ &'static std::ffi::OsStr) -> Self {
70+
Self::from_static_ref(*name)
71+
}
72+
}
73+
74+
impl From<&'static str> for OsStr {
75+
fn from(name: &'static str) -> Self {
76+
Self::from_static_ref(name.as_ref())
77+
}
78+
}
79+
80+
impl From<&'_ &'static str> for OsStr {
81+
fn from(name: &'_ &'static str) -> Self {
82+
Self::from_static_ref((*name).as_ref())
83+
}
84+
}
85+
86+
impl std::fmt::Debug for OsStr {
87+
#[inline]
88+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89+
std::fmt::Debug::fmt(self.as_os_str(), f)
90+
}
91+
}
92+
93+
impl std::ops::Deref for OsStr {
94+
type Target = std::ffi::OsStr;
95+
96+
#[inline]
97+
fn deref(&self) -> &std::ffi::OsStr {
98+
self.as_os_str()
99+
}
100+
}
101+
102+
impl AsRef<std::ffi::OsStr> for OsStr {
103+
#[inline]
104+
fn as_ref(&self) -> &std::ffi::OsStr {
105+
self.as_os_str()
106+
}
107+
}
108+
109+
impl AsRef<std::path::Path> for OsStr {
110+
#[inline]
111+
fn as_ref(&self) -> &std::path::Path {
112+
std::path::Path::new(self)
113+
}
114+
}
115+
116+
impl std::borrow::Borrow<std::ffi::OsStr> for OsStr {
117+
#[inline]
118+
fn borrow(&self) -> &std::ffi::OsStr {
119+
self.as_os_str()
120+
}
121+
}
122+
123+
impl PartialEq<str> for OsStr {
124+
#[inline]
125+
fn eq(&self, other: &str) -> bool {
126+
PartialEq::eq(self.as_os_str(), other)
127+
}
128+
}
129+
130+
impl PartialEq<&'_ str> for OsStr {
131+
#[inline]
132+
fn eq(&self, other: &&str) -> bool {
133+
PartialEq::eq(self.as_os_str(), *other)
134+
}
135+
}
136+
137+
impl<'s> PartialEq<&'s std::ffi::OsStr> for OsStr {
138+
#[inline]
139+
fn eq(&self, other: &&std::ffi::OsStr) -> bool {
140+
PartialEq::eq(self.as_os_str(), *other)
141+
}
142+
}
143+
144+
impl PartialEq<std::string::String> for OsStr {
145+
#[inline]
146+
fn eq(&self, other: &std::string::String) -> bool {
147+
PartialEq::eq(self.as_os_str(), other.as_str())
148+
}
149+
}
150+
151+
impl PartialEq<std::ffi::OsString> for OsStr {
152+
#[inline]
153+
fn eq(&self, other: &std::ffi::OsString) -> bool {
154+
PartialEq::eq(self.as_os_str(), other.as_os_str())
155+
}
156+
}
157+
158+
#[derive(Clone)]
159+
enum Inner {
160+
Static(&'static std::ffi::OsStr),
161+
Owned(Box<std::ffi::OsStr>),
162+
}
163+
164+
impl Inner {
165+
fn as_os_str(&self) -> &std::ffi::OsStr {
166+
match self {
167+
Self::Static(s) => s,
168+
Self::Owned(s) => s.as_ref(),
169+
}
170+
}
171+
}
172+
173+
impl Default for Inner {
174+
fn default() -> Self {
175+
Self::Static(std::ffi::OsStr::new(""))
176+
}
177+
}
178+
179+
impl PartialEq for Inner {
180+
fn eq(&self, other: &Inner) -> bool {
181+
self.as_os_str() == other.as_os_str()
182+
}
183+
}
184+
185+
impl PartialOrd for Inner {
186+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
187+
self.as_os_str().partial_cmp(other.as_os_str())
188+
}
189+
}
190+
191+
impl Ord for Inner {
192+
fn cmp(&self, other: &Inner) -> std::cmp::Ordering {
193+
self.as_os_str().cmp(other.as_os_str())
194+
}
195+
}
196+
197+
impl Eq for Inner {}
198+
199+
impl std::hash::Hash for Inner {
200+
#[inline]
201+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
202+
self.as_os_str().hash(state);
203+
}
204+
}

Diff for: src/util/str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl PartialEq<str> for Str {
124124
}
125125
}
126126

127-
impl<'s> PartialEq<&'s str> for Str {
127+
impl PartialEq<&'_ str> for Str {
128128
#[inline]
129129
fn eq(&self, other: &&str) -> bool {
130130
PartialEq::eq(self.as_str(), *other)

0 commit comments

Comments
 (0)