use std::fmt::Debug; pub struct CastFailure { value: U, _marker: std::marker::PhantomData, } impl Debug for CastFailure { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("CastFailure") .field("value", &self.value) .finish() } } impl From for CastFailure { fn from(value: U) -> Self { Self { value, _marker: std::marker::PhantomData, } } } impl std::fmt::Display for CastFailure { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "cast failed: value {:?} of type `{}` could not be represented by type `{}`", self.value, std::any::type_name::(), std::any::type_name::(), ) } } impl std::error::Error for CastFailure {} impl CastFailure { #[cold] fn panic(self) -> ! { panic!("{}", self); } } pub fn try_cast( n: U, ) -> Result> { T::from(n).ok_or_else(move || n.into()) } pub fn cast(n: U) -> T { try_cast(n).unwrap_or_else(move |err| err.panic()) }