nu_utils/downcast.rs
1use std::any::Any;
2
3/// On-stack downcasting for specialization in generic functions.
4/// ```
5/// # use std::any::Any;
6/// # use std::fmt::Display;
7/// # use nu_utils::downcast;
8/// fn foo<T: Display + Any>(x: T) {
9/// match downcast::<T, usize>(x) {
10/// Ok(x) => println!("usize: {x}"),
11/// Err(x) => println!("other: {x}"),
12/// }
13/// }
14/// ```
15pub fn downcast<T: Any, Target: Any>(x: T) -> Result<Target, T> {
16 let mut x = Some(x);
17 let x: &mut dyn Any = &mut x;
18
19 if let Some(target) = x.downcast_mut::<Option<Target>>().and_then(Option::take) {
20 Ok(target)
21 } else {
22 let x = x
23 .downcast_mut::<Option<T>>()
24 .and_then(Option::take)
25 .expect("downcasting to same type can't fail");
26 Err(x)
27 }
28}