zwave 0.0.1

Control Z-Wave networks with Rust.
macro_rules! def_any {
    ($name:ident : $bound:ident) => {
        pub struct $name {
            type_id: ::std::any::TypeId,
            object: Box<$bound>,
        }

        impl $name {
            pub fn new<T: $bound>(object: T) -> Self {
                $name {
                    type_id: ::std::any::TypeId::of::<T>(),
                    object: Box::new(object),
                }
            }

            pub fn is<T: $bound>(&self) -> bool {
                ::std::any::TypeId::of::<T>() == self.type_id
            }

            pub fn downcast_ref<T: $bound>(&self) -> Option<&T> {
                if self.is::<T>() {
                    unsafe {
                        let fat_ptr: ::std::raw::TraitObject = ::std::mem::transmute(::std::ops::Deref::deref(self));

                        Some(&*(fat_ptr.data as *const T))
                    }
                }
                else {
                    None
                }
            }

            pub fn downcast<T: $bound>(self) -> Result<Box<T>, Self> {
                if self.is::<T>() {
                    unsafe {
                        let raw = Box::into_raw(self.object);
                        let fat_ptr: ::std::raw::TraitObject = ::std::mem::transmute(raw);

                        Ok(Box::from_raw(fat_ptr.data as *mut T))
                    }
                }
                else {
                    Err(self)
                }
            }
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
                ::std::fmt::Debug::fmt(&self.object, fmt)
            }
        }

        impl ::std::ops::Deref for $name {
            type Target = $bound;

            fn deref(&self) -> &$bound {
                ::std::ops::Deref::deref(&self.object)
            }
        }

        impl ::std::ops::DerefMut for $name {
            fn deref_mut(&mut self) -> &mut $bound {
                ::std::ops::DerefMut::deref_mut(&mut self.object)
            }
        }

        impl ::std::borrow::Borrow<$bound> for $name {
            fn borrow(&self) -> &$bound {
                ::std::borrow::Borrow::borrow(&self.object)
            }
        }

        impl ::std::borrow::BorrowMut<$bound> for $name {
            fn borrow_mut(&mut self) -> &mut $bound {
                ::std::borrow::BorrowMut::borrow_mut(&mut self.object)
            }
        }
    }
}