From 19f935aa61f76d0fa2b2ce799bc9c252228c9c71 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 2 Aug 2024 09:46:44 -0500 Subject: [PATCH] feat(builder): Add Extension API --- Cargo.toml | 1 + clap_builder/Cargo.toml | 1 + clap_builder/src/builder/arg.rs | 33 +++++++++++++++++++++++++++++++++ clap_builder/src/builder/ext.rs | 6 ++---- clap_builder/src/builder/mod.rs | 2 ++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 86f9ab71..f4f3f97f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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] diff --git a/clap_builder/Cargo.toml b/clap_builder/Cargo.toml index 1948024c..5ae18d9c 100644 --- a/clap_builder/Cargo.toml +++ b/clap_builder/Cargo.toml @@ -52,6 +52,7 @@ string = [] # Allow runtime generated strings # In-work features unstable-v5 = ["deprecated"] +unstable-ext = [] unstable-styles = ["color"] # deprecated [lib] diff --git a/clap_builder/src/builder/arg.rs b/clap_builder/src/builder/arg.rs index a40d0cca..a6473d96 100644 --- a/clap_builder/src/builder/arg.rs +++ b/clap_builder/src/builder/arg.rs @@ -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, pub(crate) help_heading: Option>, pub(crate) value_hint: Option, + #[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(&mut self, tagged: T) -> bool { + self.ext.set(tagged) + } + + /// Remove an [`ArgExt`] + #[cfg(feature = "unstable-ext")] + pub fn remove(&mut self) -> Option { + self.ext.remove::() + } } /// # 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(&self) -> Option<&T> { + self.ext.get::() + } } /// # 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 { diff --git a/clap_builder/src/builder/ext.rs b/clap_builder/src/builder/ext.rs index 9c5c0374..974b61cb 100644 --- a/clap_builder/src/builder/ext.rs +++ b/clap_builder/src/builder/ext.rs @@ -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 Extension for T where T: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {} diff --git a/clap_builder/src/builder/mod.rs b/clap_builder/src/builder/mod.rs index 320a4534..b428fb03 100644 --- a/clap_builder/src/builder/mod.rs +++ b/clap_builder/src/builder/mod.rs @@ -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;