diff options
Diffstat (limited to 'vendor/clap_builder/src/builder/ext.rs')
-rw-r--r-- | vendor/clap_builder/src/builder/ext.rs | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/vendor/clap_builder/src/builder/ext.rs b/vendor/clap_builder/src/builder/ext.rs deleted file mode 100644 index 2fb0d96..0000000 --- a/vendor/clap_builder/src/builder/ext.rs +++ /dev/null @@ -1,216 +0,0 @@ -use crate::util::AnyValueId; -use crate::util::FlatMap; - -#[derive(Default, Clone, Debug)] -pub(crate) struct Extensions { - extensions: FlatMap<AnyValueId, BoxedExtension>, -} - -impl Extensions { - #[allow(dead_code)] - pub(crate) fn get<T: Extension>(&self) -> Option<&T> { - let id = AnyValueId::of::<T>(); - self.extensions.get(&id).map(|e| e.as_ref::<T>()) - } - - #[allow(dead_code)] - pub(crate) fn get_mut<T: Extension>(&mut self) -> Option<&mut T> { - let id = AnyValueId::of::<T>(); - self.extensions.get_mut(&id).map(|e| e.as_mut::<T>()) - } - - #[allow(dead_code)] - pub(crate) fn get_or_insert_default<T: Extension + Default>(&mut self) -> &mut T { - let id = AnyValueId::of::<T>(); - self.extensions - .entry(id) - .or_insert_with(|| BoxedExtension::new(T::default())) - .as_mut::<T>() - } - - #[allow(dead_code)] - pub(crate) fn set<T: Extension + Into<BoxedEntry>>(&mut self, tagged: T) -> bool { - let BoxedEntry { id, value } = tagged.into(); - self.extensions.insert(id, value).is_some() - } - - #[allow(dead_code)] - pub(crate) fn remove<T: Extension>(&mut self) -> Option<Box<dyn Extension>> { - let id = AnyValueId::of::<T>(); - self.extensions.remove(&id).map(BoxedExtension::into_inner) - } - - pub(crate) fn update(&mut self, other: &Self) { - for (key, value) in other.extensions.iter() { - self.extensions.insert(*key, value.clone()); - } - } -} - -/// Supports conversion to `Any`. Traits to be extended by `impl_downcast!` must extend `Extension`. -pub(crate) trait Extension: std::fmt::Debug + Send + Sync + 'static { - /// Convert `Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Any>`. - /// - /// `Box<dyn Any>` can /// then be further `downcast` into - /// `Box<ConcreteType>` where `ConcreteType` implements `Trait`. - fn into_any(self: Box<Self>) -> Box<dyn std::any::Any>; - /// Clone `&Box<dyn Trait>` (where `Trait: Extension`) to `Box<dyn Extension>`. - /// - /// `Box<dyn Any>` can /// then be further `downcast` into - // `Box<ConcreteType>` where `ConcreteType` implements `Trait`. - fn clone_extension(&self) -> Box<dyn Extension>; - /// Convert `&Trait` (where `Trait: Extension`) to `&Any`. - /// - /// This is needed since Rust cannot /// generate `&Any`'s vtable from - /// `&Trait`'s. - fn as_any(&self) -> &dyn std::any::Any; - /// Convert `&mut Trait` (where `Trait: Extension`) to `&Any`. - /// - /// This is needed since Rust cannot /// generate `&mut Any`'s vtable from - /// `&mut Trait`'s. - fn as_any_mut(&mut self) -> &mut dyn std::any::Any; -} - -impl<T> Extension for T -where - T: Clone + std::fmt::Debug + Send + Sync + 'static, -{ - fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> { - self - } - fn clone_extension(&self) -> Box<dyn Extension> { - Box::new(self.clone()) - } - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self - } -} - -impl Clone for Box<dyn Extension> { - fn clone(&self) -> Self { - self.as_ref().clone_extension() - } -} - -#[derive(Clone)] -#[repr(transparent)] -struct BoxedExtension(Box<dyn Extension>); - -impl BoxedExtension { - fn new<T: Extension>(inner: T) -> Self { - Self(Box::new(inner)) - } - - fn into_inner(self) -> Box<dyn Extension> { - self.0 - } - - fn as_ref<T: Extension>(&self) -> &T { - self.0.as_ref().as_any().downcast_ref::<T>().unwrap() - } - - fn as_mut<T: Extension>(&mut self) -> &mut T { - self.0.as_mut().as_any_mut().downcast_mut::<T>().unwrap() - } -} - -impl std::fmt::Debug for BoxedExtension { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - self.0.fmt(f) - } -} - -#[derive(Clone)] -pub(crate) struct BoxedEntry { - id: AnyValueId, - value: BoxedExtension, -} - -impl BoxedEntry { - pub(crate) fn new(r: impl Extension) -> Self { - let id = AnyValueId::from(&r); - let value = BoxedExtension::new(r); - BoxedEntry { id, value } - } -} - -impl<R: Extension> From<R> for BoxedEntry { - fn from(inner: R) -> Self { - BoxedEntry::new(inner) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)] - struct Number(usize); - - #[test] - fn get() { - let mut ext = Extensions::default(); - ext.set(Number(10)); - assert_eq!(ext.get::<Number>(), Some(&Number(10))); - } - - #[test] - fn get_mut() { - let mut ext = Extensions::default(); - ext.set(Number(10)); - *ext.get_mut::<Number>().unwrap() = Number(20); - assert_eq!(ext.get::<Number>(), Some(&Number(20))); - } - - #[test] - fn get_or_insert_default_empty() { - let mut ext = Extensions::default(); - assert_eq!(ext.get_or_insert_default::<Number>(), &Number(0)); - } - - #[test] - fn get_or_insert_default_full() { - let mut ext = Extensions::default(); - ext.set(Number(10)); - assert_eq!(ext.get_or_insert_default::<Number>(), &Number(10)); - } - - #[test] - fn set() { - let mut ext = Extensions::default(); - assert!(!ext.set(Number(10))); - assert_eq!(ext.get::<Number>(), Some(&Number(10))); - assert!(ext.set(Number(20))); - assert_eq!(ext.get::<Number>(), Some(&Number(20))); - } - - #[test] - fn reset() { - let mut ext = Extensions::default(); - assert_eq!(ext.get::<Number>(), None); - - assert!(ext.remove::<Number>().is_none()); - assert_eq!(ext.get::<Number>(), None); - - assert!(!ext.set(Number(10))); - assert_eq!(ext.get::<Number>(), Some(&Number(10))); - - assert!(ext.remove::<Number>().is_some()); - assert_eq!(ext.get::<Number>(), None); - } - - #[test] - fn update() { - let mut ext = Extensions::default(); - assert_eq!(ext.get::<Number>(), None); - - let mut new = Extensions::default(); - assert!(!new.set(Number(10))); - - ext.update(&new); - assert_eq!(ext.get::<Number>(), Some(&Number(10))); - } -} |