Skip to main content

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}