feat(builder): Add Extension API

This commit is contained in:
Ed Page 2024-08-02 09:46:44 -05:00
parent 280d921dee
commit 19f935aa61
5 changed files with 39 additions and 4 deletions

View file

@ -168,6 +168,7 @@ string = ["clap_builder/string"] # Allow runtime generated strings
# In-work features
unstable-v5 = ["clap_builder/unstable-v5", "clap_derive?/unstable-v5", "deprecated"]
unstable-ext = []
unstable-styles = ["clap_builder/unstable-styles"] # deprecated
[lib]

View file

@ -52,6 +52,7 @@ string = [] # Allow runtime generated strings
# In-work features
unstable-v5 = ["deprecated"]
unstable-ext = []
unstable-styles = ["color"] # deprecated
[lib]

View file

@ -11,6 +11,10 @@ use std::{
// Internal
use super::{ArgFlags, ArgSettings};
#[cfg(feature = "unstable-ext")]
use crate::builder::ext::Extension;
#[cfg(feature = "unstable-ext")]
use crate::builder::ext::Extensions;
use crate::builder::ArgPredicate;
use crate::builder::IntoResettable;
use crate::builder::OsStr;
@ -86,6 +90,8 @@ pub struct Arg {
pub(crate) index: Option<usize>,
pub(crate) help_heading: Option<Option<Str>>,
pub(crate) value_hint: Option<ValueHint>,
#[cfg(feature = "unstable-ext")]
pub(crate) ext: Extensions,
}
/// # Basic API
@ -869,6 +875,18 @@ impl Arg {
self.settings.unset(setting);
self
}
/// Extend [`Arg`] with [`ArgExt`] data
#[cfg(feature = "unstable-ext")]
pub fn add<T: ArgExt + Extension>(&mut self, tagged: T) -> bool {
self.ext.set(tagged)
}
/// Remove an [`ArgExt`]
#[cfg(feature = "unstable-ext")]
pub fn remove<T: ArgExt + Extension>(&mut self) -> Option<T> {
self.ext.remove::<T>()
}
}
/// # Value Handling
@ -4210,6 +4228,12 @@ impl Arg {
pub fn is_ignore_case_set(&self) -> bool {
self.is_set(ArgSettings::IgnoreCase)
}
/// Access an [`ArgExt`]
#[cfg(feature = "unstable-ext")]
pub fn get<T: ArgExt + Extension>(&self) -> Option<&T> {
self.ext.get::<T>()
}
}
/// # Internally used only
@ -4492,10 +4516,19 @@ impl fmt::Debug for Arg {
ds = ds.field("env", &self.env);
}
#[cfg(feature = "unstable-ext")]
{
ds = ds.field("ext", &self.ext);
}
ds.finish()
}
}
/// User-provided data that can be attached to an [`Arg`]
#[cfg(feature = "unstable-ext")]
pub trait ArgExt: Extension {}
// Flags
#[cfg(test)]
mod test {

View file

@ -40,9 +40,7 @@ impl Extensions {
}
}
pub(crate) trait Extension:
std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static
{
}
#[allow(unreachable_pub)]
pub trait Extension: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {}
impl<T> Extension for T where T: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {}

View file

@ -28,6 +28,8 @@ pub mod styling;
pub use self::str::Str;
pub use action::ArgAction;
pub use arg::Arg;
#[cfg(feature = "unstable-ext")]
pub use arg::ArgExt;
pub use arg_group::ArgGroup;
pub use arg_predicate::ArgPredicate;
pub use command::Command;