From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Mon, 8 Jan 2024 01:21:28 +0400 Subject: Initial vendor packages Signed-off-by: Valentin Popov --- vendor/clap_builder/src/util/any_value.rs | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 vendor/clap_builder/src/util/any_value.rs (limited to 'vendor/clap_builder/src/util/any_value.rs') diff --git a/vendor/clap_builder/src/util/any_value.rs b/vendor/clap_builder/src/util/any_value.rs new file mode 100644 index 0000000..19aa82b --- /dev/null +++ b/vendor/clap_builder/src/util/any_value.rs @@ -0,0 +1,127 @@ +#[derive(Clone)] +pub(crate) struct AnyValue { + inner: std::sync::Arc, + // While we can extract `TypeId` from `inner`, the debug repr is of a number, so let's track + // the type_name in debug builds. + id: AnyValueId, +} + +impl AnyValue { + pub(crate) fn new(inner: V) -> Self { + let id = AnyValueId::of::(); + let inner = std::sync::Arc::new(inner); + Self { inner, id } + } + + pub(crate) fn downcast_ref( + &self, + ) -> Option<&T> { + self.inner.downcast_ref::() + } + + pub(crate) fn downcast_into(self) -> Result { + let id = self.id; + let value = + ok!(std::sync::Arc::downcast::(self.inner).map_err(|inner| Self { inner, id })); + let value = std::sync::Arc::try_unwrap(value).unwrap_or_else(|arc| (*arc).clone()); + Ok(value) + } + + pub(crate) fn type_id(&self) -> AnyValueId { + self.id + } +} + +impl std::fmt::Debug for AnyValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + f.debug_struct("AnyValue").field("inner", &self.id).finish() + } +} + +#[derive(Copy, Clone)] +pub struct AnyValueId { + type_id: std::any::TypeId, + #[cfg(debug_assertions)] + type_name: &'static str, +} + +impl AnyValueId { + pub(crate) fn of() -> Self { + Self { + type_id: std::any::TypeId::of::(), + #[cfg(debug_assertions)] + type_name: std::any::type_name::(), + } + } +} + +impl PartialEq for AnyValueId { + fn eq(&self, other: &Self) -> bool { + self.type_id == other.type_id + } +} + +impl Eq for AnyValueId {} + +impl PartialOrd for AnyValueId { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for AnyValueId { + fn eq(&self, other: &std::any::TypeId) -> bool { + self.type_id == *other + } +} + +impl Ord for AnyValueId { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.type_id.cmp(&other.type_id) + } +} + +impl std::hash::Hash for AnyValueId { + fn hash(&self, state: &mut H) { + self.type_id.hash(state); + } +} + +impl std::fmt::Debug for AnyValueId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + #[cfg(not(debug_assertions))] + { + self.type_id.fmt(f) + } + #[cfg(debug_assertions)] + { + f.debug_struct(self.type_name).finish() + } + } +} + +impl<'a, A: ?Sized + 'static> From<&'a A> for AnyValueId { + fn from(_: &'a A) -> Self { + Self::of::() + } +} + +#[cfg(test)] +mod test { + #[test] + #[cfg(debug_assertions)] + fn debug_impl() { + use super::*; + + assert_eq!(format!("{:?}", AnyValue::new(5)), "AnyValue { inner: i32 }"); + } + + #[test] + fn eq_to_type_id() { + use super::*; + + let any_value_id = AnyValueId::of::(); + let type_id = std::any::TypeId::of::(); + assert_eq!(any_value_id, type_id); + } +} -- cgit v1.2.3