From 063f5d69e61219de7ade690081b7996bbc25eca3 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 15 Aug 2022 14:18:38 -0500 Subject: [PATCH] fix!: Remove lifetime from PossibleValue Another step towards #1041 This isn't the long term type for `PossibleValue::help`, I just wanted to get the lifetime out of the way first before figuring out how help will work. --- clap_complete/src/dynamic.rs | 2 +- clap_complete/src/generator/utils.rs | 2 +- clap_complete/src/shells/bash.rs | 3 +- clap_complete/src/shells/fish.rs | 3 +- clap_complete/src/shells/shell.rs | 2 +- clap_complete/src/shells/zsh.rs | 11 +++-- clap_derive/src/attrs.rs | 17 +++---- clap_derive/src/derives/value_enum.rs | 2 +- clap_derive/src/dummies.rs | 2 +- examples/tutorial_builder/04_01_enum.rs | 2 +- src/builder/arg.rs | 2 +- src/builder/possible_value.rs | 64 +++++++++++-------------- src/builder/value_parser.rs | 42 ++++++++-------- src/derive.rs | 2 +- src/error/mod.rs | 4 +- src/lib.rs | 2 +- src/output/help.rs | 2 +- src/parser/parser.rs | 3 +- src/parser/validator.rs | 4 +- src/util/mod.rs | 1 + src/util/os_str.rs | 18 +++++++ src/util/str.rs | 6 ++- 22 files changed, 104 insertions(+), 92 deletions(-) diff --git a/clap_complete/src/dynamic.rs b/clap_complete/src/dynamic.rs index 3bf0088e753f..4f32658ebbba 100644 --- a/clap_complete/src/dynamic.rs +++ b/clap_complete/src/dynamic.rs @@ -231,7 +231,7 @@ complete OPTIONS -F _clap_complete_NAME EXECUTABLES Self::Menu, ] } - fn to_possible_value<'a>(&self) -> ::std::option::Option> { + fn to_possible_value(&self) -> ::std::option::Option { match self { Self::Normal => { let value = "9"; diff --git a/clap_complete/src/generator/utils.rs b/clap_complete/src/generator/utils.rs index 27bf807808f1..85988012beef 100644 --- a/clap_complete/src/generator/utils.rs +++ b/clap_complete/src/generator/utils.rs @@ -127,7 +127,7 @@ pub fn flags<'help>(p: &Command<'help>) -> Vec> { } /// Get the possible values for completion -pub fn possible_values<'help>(a: &Arg<'help>) -> Option>> { +pub fn possible_values(a: &Arg<'_>) -> Option> { if !a.get_num_args().expect("built").takes_values() { None } else { diff --git a/clap_complete/src/shells/bash.rs b/clap_complete/src/shells/bash.rs index ef155dd2fe76..86f462183541 100644 --- a/clap_complete/src/shells/bash.rs +++ b/clap_complete/src/shells/bash.rs @@ -1,6 +1,5 @@ use std::{fmt::Write as _, io::Write}; -use clap::builder::PossibleValue; use clap::*; use crate::generator::{utils, Generator}; @@ -180,7 +179,7 @@ fn vals_for(o: &Arg) -> String { "$(compgen -W \"{}\" -- \"${{cur}}\")", vals.iter() .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) + .map(|n| n.get_name().as_str()) .collect::>() .join(" ") ) diff --git a/clap_complete/src/shells/fish.rs b/clap_complete/src/shells/fish.rs index 2550a22989b5..d57802c7aa72 100644 --- a/clap_complete/src/shells/fish.rs +++ b/clap_complete/src/shells/fish.rs @@ -164,7 +164,8 @@ fn value_completion(option: &Arg) -> String { Some(format!( "{}\t{}", escape_string(value.get_name()).as_str(), - escape_string(value.get_help().unwrap_or_default()).as_str() + escape_string(value.get_help().map(|s| s.as_str()).unwrap_or_default()) + .as_str() )) }) .collect::>() diff --git a/clap_complete/src/shells/shell.rs b/clap_complete/src/shells/shell.rs index c47f596618c1..35db04168699 100644 --- a/clap_complete/src/shells/shell.rs +++ b/clap_complete/src/shells/shell.rs @@ -57,7 +57,7 @@ impl ValueEnum for Shell { ] } - fn to_possible_value<'a>(&self) -> Option> { + fn to_possible_value<'a>(&self) -> Option { Some(match self { Shell::Bash => PossibleValue::new("bash"), Shell::Elvish => PossibleValue::new("elvish"), diff --git a/clap_complete/src/shells/zsh.rs b/clap_complete/src/shells/zsh.rs index 814c7ffc4070..7594d780e7b7 100644 --- a/clap_complete/src/shells/zsh.rs +++ b/clap_complete/src/shells/zsh.rs @@ -1,6 +1,5 @@ use std::io::Write; -use clap::builder::PossibleValue; use clap::*; use crate::generator::{utils, Generator}; @@ -375,8 +374,12 @@ fn value_completion(arg: &Arg) -> Option { } else { Some(format!( r#"{name}\:"{tooltip}""#, - name = escape_value(value.get_name()), - tooltip = value.get_help().map(escape_help).unwrap_or_default() + name = escape_value(value.get_name().as_str()), + tooltip = value + .get_help() + .map(|s| s.as_str()) + .map(escape_help) + .unwrap_or_default() )) } }) @@ -389,7 +392,7 @@ fn value_completion(arg: &Arg) -> Option { values .iter() .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) + .map(|n| n.get_name().as_str()) .collect::>() .join(" ") )) diff --git a/clap_derive/src/attrs.rs b/clap_derive/src/attrs.rs index 79c109d3a2ce..1ac6693eb254 100644 --- a/clap_derive/src/attrs.rs +++ b/clap_derive/src/attrs.rs @@ -499,7 +499,7 @@ impl Attrs { quote_spanned!(ident.span()=> { { let val: #ty = #val; - clap::ValueEnum::to_possible_value(&val).unwrap().get_name() + clap::ValueEnum::to_possible_value(&val).unwrap().get_name().to_owned() } }) } else { @@ -544,17 +544,15 @@ impl Attrs { let val = if parsed.iter().any(|a| matches!(a, ValueEnum(_))) { quote_spanned!(ident.span()=> { { - fn iter_to_vals(iterable: impl IntoIterator) -> Vec<&'static str> + fn iter_to_vals(iterable: impl IntoIterator) -> impl Iterator where T: ::std::borrow::Borrow<#inner_type> { iterable .into_iter() .map(|val| { - clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name() + clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name().to_owned() }) - .collect() - } iter_to_vals(#expr) @@ -603,7 +601,7 @@ impl Attrs { quote_spanned!(ident.span()=> { { let val: #ty = #val; - clap::ValueEnum::to_possible_value(&val).unwrap().get_name() + clap::ValueEnum::to_possible_value(&val).unwrap().get_name().to_owned() } }) } else { @@ -648,18 +646,15 @@ impl Attrs { let val = if parsed.iter().any(|a| matches!(a, ValueEnum(_))) { quote_spanned!(ident.span()=> { { - fn iter_to_vals(iterable: impl IntoIterator) -> Vec<&'static ::std::ffi::OsStr> + fn iter_to_vals(iterable: impl IntoIterator) -> impl Iterator where T: ::std::borrow::Borrow<#inner_type> { iterable .into_iter() .map(|val| { - clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name() + clap::ValueEnum::to_possible_value(val.borrow()).unwrap().get_name().to_owned() }) - .map(::std::ffi::OsStr::new) - .collect() - } iter_to_vals(#expr) diff --git a/clap_derive/src/derives/value_enum.rs b/clap_derive/src/derives/value_enum.rs index 7b0726220d98..f08476741587 100644 --- a/clap_derive/src/derives/value_enum.rs +++ b/clap_derive/src/derives/value_enum.rs @@ -114,7 +114,7 @@ fn gen_to_possible_value(lits: &[(TokenStream, Ident)]) -> TokenStream { let (lit, variant): (Vec, Vec) = lits.iter().cloned().unzip(); quote! { - fn to_possible_value<'a>(&self) -> ::std::option::Option> { + fn to_possible_value<'a>(&self) -> ::std::option::Option { match self { #(Self::#variant => Some(#lit),)* _ => None diff --git a/clap_derive/src/dummies.rs b/clap_derive/src/dummies.rs index 51740c75e874..164c211ef760 100644 --- a/clap_derive/src/dummies.rs +++ b/clap_derive/src/dummies.rs @@ -82,7 +82,7 @@ pub fn value_enum(name: &Ident) { fn from_str(_input: &str, _ignore_case: bool) -> ::std::result::Result { unimplemented!() } - fn to_possible_value<'a>(&self) -> ::std::option::Option>{ + fn to_possible_value<'a>(&self) -> ::std::option::Option{ unimplemented!() } } diff --git a/examples/tutorial_builder/04_01_enum.rs b/examples/tutorial_builder/04_01_enum.rs index 85d452fad3a6..3f8ddd3a83d8 100644 --- a/examples/tutorial_builder/04_01_enum.rs +++ b/examples/tutorial_builder/04_01_enum.rs @@ -12,7 +12,7 @@ impl ValueEnum for Mode { &[Mode::Fast, Mode::Slow] } - fn to_possible_value<'a>(&self) -> Option> { + fn to_possible_value<'a>(&self) -> Option { Some(match self { Mode::Fast => PossibleValue::new("fast"), Mode::Slow => PossibleValue::new("slow"), diff --git a/src/builder/arg.rs b/src/builder/arg.rs index 648f495ed8ea..008e4a50de5e 100644 --- a/src/builder/arg.rs +++ b/src/builder/arg.rs @@ -3659,7 +3659,7 @@ impl<'help> Arg<'help> { Some(longs) } - pub(crate) fn get_possible_values(&self) -> Vec> { + pub(crate) fn get_possible_values(&self) -> Vec { if !self.is_takes_value_set() { vec![] } else { diff --git a/src/builder/possible_value.rs b/src/builder/possible_value.rs index d795013edf2b..d87507d9c7e7 100644 --- a/src/builder/possible_value.rs +++ b/src/builder/possible_value.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, iter}; use crate::util::eq_ignore_case; +use crate::Str; /// A possible value of an argument. /// @@ -27,14 +28,14 @@ use crate::util::eq_ignore_case; /// [hide]: PossibleValue::hide() /// [help]: PossibleValue::help() #[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct PossibleValue<'help> { - name: &'help str, - help: Option<&'help str>, - aliases: Vec<&'help str>, // (name, visible) +pub struct PossibleValue { + name: Str, + help: Option, + aliases: Vec, // (name, visible) hide: bool, } -impl<'help> PossibleValue<'help> { +impl PossibleValue { /// Create a [`PossibleValue`] with its name. /// /// The name will be used to decide whether this value was provided by the user to an argument. @@ -52,9 +53,9 @@ impl<'help> PossibleValue<'help> { /// [hidden]: PossibleValue::hide /// [possible value]: crate::builder::PossibleValuesParser /// [`Arg::hide_possible_values(true)`]: crate::Arg::hide_possible_values() - pub fn new(name: &'help str) -> Self { + pub fn new(name: impl Into) -> Self { PossibleValue { - name, + name: name.into(), ..Default::default() } } @@ -74,8 +75,8 @@ impl<'help> PossibleValue<'help> { /// ``` #[inline] #[must_use] - pub fn help(mut self, help: &'help str) -> Self { - self.help = Some(help); + pub fn help(mut self, help: impl Into) -> Self { + self.help = Some(help.into()); self } @@ -111,8 +112,8 @@ impl<'help> PossibleValue<'help> { /// # ; /// ``` #[must_use] - pub fn alias(mut self, name: &'help str) -> Self { - self.aliases.push(name); + pub fn alias(mut self, name: impl Into) -> Self { + self.aliases.push(name.into()); self } @@ -127,35 +128,32 @@ impl<'help> PossibleValue<'help> { /// # ; /// ``` #[must_use] - pub fn aliases(mut self, names: I) -> Self - where - I: IntoIterator, - { - self.aliases.extend(names.into_iter()); + pub fn aliases(mut self, names: impl IntoIterator>) -> Self { + self.aliases.extend(names.into_iter().map(|a| a.into())); self } } /// Reflection -impl<'help> PossibleValue<'help> { +impl PossibleValue { /// Get the name of the argument value #[inline] - pub fn get_name(&self) -> &'help str { - self.name + pub fn get_name(&self) -> &Str { + &self.name } /// Get the help specified for this argument, if any #[inline] - pub fn get_help(&self) -> Option<&'help str> { - self.help + pub fn get_help(&self) -> Option<&Str> { + self.help.as_ref() } /// Get the help specified for this argument, if any and the argument /// value is not hidden #[inline] - pub(crate) fn get_visible_help(&self) -> Option<&'help str> { + pub(crate) fn get_visible_help(&self) -> Option<&str> { if !self.hide { - self.help + self.help.as_deref() } else { None } @@ -174,12 +172,12 @@ impl<'help> PossibleValue<'help> { /// Get the name if argument value is not hidden, `None` otherwise, /// but wrapped in quotes if it contains whitespace - pub(crate) fn get_visible_quoted_name(&self) -> Option> { + pub(crate) fn get_visible_quoted_name(&self) -> Option> { if !self.hide { Some(if self.name.contains(char::is_whitespace) { format!("{:?}", self.name).into() } else { - self.name.into() + self.name.as_str().into() }) } else { None @@ -189,8 +187,8 @@ impl<'help> PossibleValue<'help> { /// Returns all valid values of the argument value. /// /// Namely the name and all aliases. - pub fn get_name_and_aliases(&self) -> impl Iterator + '_ { - iter::once(&self.name).chain(&self.aliases).copied() + pub fn get_name_and_aliases(&self) -> impl Iterator + '_ { + iter::once(&self.name).chain(self.aliases.iter()) } /// Tests if the value is valid for this argument value @@ -212,21 +210,15 @@ impl<'help> PossibleValue<'help> { pub fn matches(&self, value: &str, ignore_case: bool) -> bool { if ignore_case { self.get_name_and_aliases() - .any(|name| eq_ignore_case(name, value)) + .any(|name| eq_ignore_case(name.as_str(), value)) } else { self.get_name_and_aliases().any(|name| name == value) } } } -impl<'help> From<&'help str> for PossibleValue<'help> { - fn from(s: &'help str) -> Self { - Self::new(s) - } -} - -impl<'help> From<&'_ &'help str> for PossibleValue<'help> { - fn from(s: &'_ &'help str) -> Self { +impl> From for PossibleValue { + fn from(s: S) -> Self { Self::new(s) } } diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 769d1a70a993..f94d45f64bd1 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -243,7 +243,7 @@ impl ValueParser { /// applications like errors and completion. pub fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { self.any_value_parser().possible_values() } @@ -501,7 +501,7 @@ impl From for ValueParser { /// ``` impl From<[P; C]> for ValueParser where - P: Into>, + P: Into, { fn from(values: [P; C]) -> Self { let inner = PossibleValuesParser::from(values); @@ -554,7 +554,7 @@ trait AnyValueParser: Send + Sync + 'static { fn possible_values( &self, - ) -> Option> + '_>>; + ) -> Option + '_>>; fn clone_any(&self) -> Box; } @@ -590,7 +590,7 @@ where fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { P::possible_values(self) } @@ -632,7 +632,7 @@ pub trait TypedValueParser: Clone + Send + Sync + 'static { /// applications like errors and completion. fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { None } @@ -876,7 +876,7 @@ impl Default for PathBufValueParser { /// &[Self::Always, Self::Auto, Self::Never] /// } /// -/// fn to_possible_value<'a>(&self) -> Option> { +/// fn to_possible_value<'a>(&self) -> Option { /// match self { /// Self::Always => Some(clap::builder::PossibleValue::new("always")), /// Self::Auto => Some(clap::builder::PossibleValue::new("auto")), @@ -936,7 +936,7 @@ impl TypedValueParser for E .iter() .filter_map(|v| v.to_possible_value()) .filter(|v| !v.is_hide_set()) - .map(|v| v.get_name()) + .map(|v| v.get_name().as_str().to_owned()) .collect::>() }; @@ -971,7 +971,7 @@ impl TypedValueParser for E fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { Some(Box::new( E::value_variants() .iter() @@ -1022,7 +1022,7 @@ impl Default for EnumValueP /// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), "never"); /// ``` #[derive(Clone, Debug)] -pub struct PossibleValuesParser(Vec>); +pub struct PossibleValuesParser(Vec); impl PossibleValuesParser { /// Verify the value is from an enumerated set pf [`PossibleValue`][crate::builder::PossibleValue]. @@ -1064,7 +1064,7 @@ impl TypedValueParser for PossibleValuesParser { .0 .iter() .filter(|v| !v.is_hide_set()) - .map(crate::builder::PossibleValue::get_name) + .map(|v| v.get_name().as_str().to_owned()) .collect::>(); Err(crate::Error::invalid_value( @@ -1079,7 +1079,7 @@ impl TypedValueParser for PossibleValuesParser { fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { Some(Box::new(self.0.iter().cloned())) } } @@ -1087,7 +1087,7 @@ impl TypedValueParser for PossibleValuesParser { impl From for PossibleValuesParser where I: IntoIterator, - T: Into>, + T: Into, { fn from(values: I) -> Self { Self(values.into_iter().map(|t| t.into()).collect()) @@ -1501,7 +1501,7 @@ impl BoolValueParser { Self {} } - fn possible_values() -> impl Iterator> { + fn possible_values() -> impl Iterator { ["true", "false"] .iter() .copied() @@ -1525,7 +1525,7 @@ impl TypedValueParser for BoolValueParser { } else { // Intentionally showing hidden as we hide all of them let possible_vals = Self::possible_values() - .map(|v| v.get_name()) + .map(|v| v.get_name().as_str().to_owned()) .collect::>(); return Err(crate::Error::invalid_value( @@ -1541,7 +1541,7 @@ impl TypedValueParser for BoolValueParser { fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { Some(Box::new(Self::possible_values())) } } @@ -1600,7 +1600,7 @@ impl FalseyValueParser { Self {} } - fn possible_values() -> impl Iterator> { + fn possible_values() -> impl Iterator { crate::util::TRUE_LITERALS .iter() .chain(crate::util::FALSE_LITERALS.iter()) @@ -1634,7 +1634,7 @@ impl TypedValueParser for FalseyValueParser { fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { Some(Box::new(Self::possible_values())) } } @@ -1697,7 +1697,7 @@ impl BoolishValueParser { Self {} } - fn possible_values() -> impl Iterator> { + fn possible_values() -> impl Iterator { crate::util::TRUE_LITERALS .iter() .chain(crate::util::FALSE_LITERALS.iter()) @@ -1733,7 +1733,7 @@ impl TypedValueParser for BoolishValueParser { fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { Some(Box::new(Self::possible_values())) } } @@ -1874,7 +1874,7 @@ where fn possible_values( &self, - ) -> Option> + '_>> { + ) -> Option + '_>> { self.parser.possible_values() } } @@ -2130,7 +2130,7 @@ pub mod via_prelude { /// # fn value_variants<'a>() -> &'a [Self] { /// # &[Self::Always, Self::Auto, Self::Never] /// # } -/// # fn to_possible_value<'a>(&self) -> Option> { +/// # fn to_possible_value<'a>(&self) -> Option { /// # match self { /// # Self::Always => Some(clap::builder::PossibleValue::new("always")), /// # Self::Auto => Some(clap::builder::PossibleValue::new("auto")), diff --git a/src/derive.rs b/src/derive.rs index dedfd30bfa8e..eddac73da3ff 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -387,7 +387,7 @@ pub trait ValueEnum: Sized + Clone { /// The canonical argument value. /// /// The value is `None` for skipped variants. - fn to_possible_value<'a>(&self) -> Option>; + fn to_possible_value(&self) -> Option; } impl Parser for Box { diff --git a/src/error/mod.rs b/src/error/mod.rs index 689561497274..d50334bfbf12 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -243,7 +243,7 @@ impl Error { ]) } - pub(crate) fn empty_value(cmd: &Command, good_vals: &[&str], arg: String) -> Self { + pub(crate) fn empty_value(cmd: &Command, good_vals: &[String], arg: String) -> Self { Self::invalid_value(cmd, "".to_owned(), good_vals, arg) } @@ -259,7 +259,7 @@ impl Error { pub(crate) fn invalid_value( cmd: &Command, bad_val: String, - good_vals: &[&str], + good_vals: &[String], arg: String, ) -> Self { let suggestion = suggestions::did_you_mean(&bad_val, good_vals.iter()).pop(); diff --git a/src/lib.rs b/src/lib.rs index 37aa246f0ba1..51f8b9caa11f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -110,7 +110,7 @@ pub use crate::util::color::ColorChoice; pub(crate) use crate::util::color::ColorChoice; pub use crate::util::Id; pub use crate::util::OsStr; -pub(crate) use crate::util::Str; +pub use crate::util::Str; pub use crate::derive::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum}; diff --git a/src/output/help.rs b/src/output/help.rs index 932e5b098b77..41d6e5ff4d3c 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -504,7 +504,7 @@ impl<'help, 'cmd, 'writer> Help<'help, 'cmd, 'writer> { self.none("\n")?; self.spaces(spaces)?; self.none("- ")?; - self.good(pv.get_name())?; + self.good(pv.get_name().as_str())?; if let Some(help) = pv.get_help() { debug!("Help::help: Possible Value help"); diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 444b822f0fbb..9774b140ef2f 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -9,7 +9,6 @@ use clap_lex::RawOsStr; use clap_lex::RawOsString; // Internal -use crate::builder::PossibleValue; use crate::builder::{Arg, Command}; use crate::error::Error as ClapError; use crate::error::Result as ClapResult; @@ -1266,7 +1265,7 @@ impl<'help, 'cmd> Parser<'help, 'cmd> { &super::get_possible_values_cli(arg) .iter() .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) + .map(|n| n.get_name().as_str().to_owned()) .collect::>(), arg.to_string(), )); diff --git a/src/parser/validator.rs b/src/parser/validator.rs index f29804edf0cb..20efa78bb730 100644 --- a/src/parser/validator.rs +++ b/src/parser/validator.rs @@ -45,7 +45,7 @@ impl<'help, 'cmd> Validator<'help, 'cmd> { &get_possible_values_cli(o) .iter() .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) + .map(|n| n.get_name().as_str().to_owned()) .collect::>(), o.to_string(), )); @@ -455,7 +455,7 @@ impl Conflicts { } } -pub(crate) fn get_possible_values_cli<'help>(a: &Arg<'help>) -> Vec> { +pub(crate) fn get_possible_values_cli(a: &Arg<'_>) -> Vec { if !a.is_takes_value_set() { vec![] } else { diff --git a/src/util/mod.rs b/src/util/mod.rs index 66fecae6cf28..11fabca5d8bb 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -16,6 +16,7 @@ pub(crate) use self::flat_map::Entry; pub(crate) use self::flat_map::FlatMap; pub(crate) use self::flat_set::FlatSet; pub(crate) use self::graph::ChildGraph; +pub(crate) use self::str::Inner as StrInner; pub(crate) use self::str_to_bool::str_to_bool; pub(crate) use self::str_to_bool::FALSE_LITERALS; pub(crate) use self::str_to_bool::TRUE_LITERALS; diff --git a/src/util/os_str.rs b/src/util/os_str.rs index 592e2b69b1b0..9a0ac8b16bab 100644 --- a/src/util/os_str.rs +++ b/src/util/os_str.rs @@ -40,6 +40,24 @@ impl From<&'_ OsStr> for OsStr { } } +impl From for OsStr { + fn from(id: crate::Str) -> Self { + match id.into_inner() { + crate::util::StrInner::Static(s) => Self::from_static_ref(std::ffi::OsStr::new(s)), + crate::util::StrInner::Owned(s) => Self::from_ref(std::ffi::OsStr::new(s.as_ref())), + } + } +} + +impl From<&'_ crate::Str> for OsStr { + fn from(id: &'_ crate::Str) -> Self { + match id.clone().into_inner() { + crate::util::StrInner::Static(s) => Self::from_static_ref(std::ffi::OsStr::new(s)), + crate::util::StrInner::Owned(s) => Self::from_ref(std::ffi::OsStr::new(s.as_ref())), + } + } +} + impl From for OsStr { fn from(name: std::ffi::OsString) -> Self { Self::from_string(name) diff --git a/src/util/str.rs b/src/util/str.rs index ef349a96e534..c84d5b976b61 100644 --- a/src/util/str.rs +++ b/src/util/str.rs @@ -23,6 +23,10 @@ impl Str { } } + pub(crate) fn into_inner(self) -> Inner { + self.name + } + /// Get the raw string of the `Str` pub fn as_str(&self) -> &str { self.name.as_str() @@ -139,7 +143,7 @@ impl PartialEq for Str { } #[derive(Clone)] -enum Inner { +pub(crate) enum Inner { Static(&'static str), Owned(Box), }