box_any.rs 995 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. use std::any::Any;
  2. use anyhow::Result;
  3. pub struct BoxAny(Box<dyn Any + Send + Sync + 'static>);
  4. impl BoxAny {
  5. pub fn new<T>(value: T) -> Self
  6. where
  7. T: Send + Sync + 'static,
  8. {
  9. Self(Box::new(value))
  10. }
  11. pub fn unbox_or_default<T>(self) -> T
  12. where
  13. T: Default + 'static,
  14. {
  15. match self.0.downcast::<T>() {
  16. Ok(value) => *value,
  17. Err(_) => T::default(),
  18. }
  19. }
  20. pub fn unbox_or_error<T>(self) -> Result<T>
  21. where
  22. T: Default + 'static,
  23. {
  24. match self.0.downcast::<T>() {
  25. Ok(value) => Ok(*value),
  26. Err(e) => Err(anyhow::anyhow!(
  27. "downcast error to {} failed: {:?}",
  28. std::any::type_name::<T>(),
  29. e
  30. )),
  31. }
  32. }
  33. pub fn unbox_or_none<T>(self) -> Option<T>
  34. where
  35. T: Default + 'static,
  36. {
  37. match self.0.downcast::<T>() {
  38. Ok(value) => Some(*value),
  39. Err(_) => None,
  40. }
  41. }
  42. #[allow(dead_code)]
  43. pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
  44. self.0.downcast_ref()
  45. }
  46. }