proxy-sdk 1.1.0

Write extensions for Proxy-WASM for WASM or Native environments
Documentation
use std::{
    any::Any,
    mem::ManuallyDrop,
    ops::{Deref, DerefMut},
};

pub struct DowncastBox<T: ?Sized> {
    general: Box<T>,
    any: ManuallyDrop<Box<dyn Any>>,
}

impl<T: ?Sized + Any> DowncastBox<T> {
    pub fn new<R: Sized + 'static>(value: Box<R>) -> Self
    where
        Box<R>: Into<Box<T>>,
    {
        let raw = Box::leak(value);
        let value_any: Box<R> = unsafe { Box::from_raw(raw) };
        let value_general: Box<R> = unsafe { Box::from_raw(raw) };
        let value_any: Box<dyn Any> = value_any;
        let value_general: Box<T> = value_general.into();
        Self {
            general: value_general,
            any: ManuallyDrop::new(value_any),
        }
    }

    #[allow(dead_code)]
    pub fn as_any(&self) -> &dyn Any {
        &**self.any
    }

    pub fn as_any_mut(&mut self) -> &mut dyn Any {
        &mut **self.any
    }
}

impl<T: ?Sized + Any> Deref for DowncastBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.general
    }
}

impl<T: ?Sized + Any> DerefMut for DowncastBox<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.general
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    trait T1: Any {}

    struct V1 {}

    impl From<Box<V1>> for Box<dyn T1> {
        fn from(val: Box<V1>) -> Self {
            val
        }
    }

    impl T1 for V1 {}

    #[test]
    fn test_downcast_box() {
        let mut v = DowncastBox::<dyn T1>::new::<V1>(Box::new(V1 {}));
        let _: &mut V1 = v.as_any_mut().downcast_mut().expect("invalid root type");
    }
}