use std::any::{Any, TypeId};
use unsafe_any::{UnsafeAny, UnsafeAnyExt};
mod parameter_map;
pub use self::parameter_map::*;
macro_rules! implement {
($name:ident, $base:ident, $(+ $bounds:ident)*, $(+ $other_bounds:ident)*) => {
#[allow(dead_code)]
struct $name {
name: String,
type_of: TypeId,
value: Box<$base $(+ $bounds)*>,
}
impl $name {
#[allow(dead_code)]
fn new<S: Into<String>, V: $base $(+ $bounds)* $(+ $other_bounds)*>(name: S, value: V) -> $name {
$name {
name: name.into(),
type_of: TypeId::of::<V>(),
value: Box::new(value),
}
}
}
};
}
macro_rules! implement_method {
([get_value] $name:ident, $base:ident, $(+ $bounds:ident)*, downcast) => {
impl $name {
#[allow(dead_code)]
fn get_value<V: $base $(+ $bounds)*>(self) -> Option<Box<V>> {
self.value.downcast::<V>().ok()
}
}
};
([get_value] $name:ident, $base:ident, $(+ $bounds:ident)*, downcast_unchecked) => {
impl $name {
#[allow(dead_code)]
fn get_value<V: $base $(+ $bounds)*>(self) -> Option<Box<V>> {
Some(unsafe { self.value.downcast_unchecked::<V>() })
}
}
};
}
implement!(Parameter,Any,,);
implement_method!([get_value] Parameter,Any,,downcast);
impl ::std::fmt::Debug for Parameter {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
write!(f, "Parameter {{name: {:?}, type_of: {:?}, value: {:?} }}", &self.name, &self.type_of, &self.value)
}
}
implement!(SendParameter,Any,+Send,);
implement_method!([get_value] SendParameter,Any,+Send,downcast);
implement!(UnsafeParameter,UnsafeAny,,);
implement_method!([get_value] UnsafeParameter,UnsafeAny,, downcast_unchecked);
implement!(UnsafeSendSyncParameter,UnsafeAny,+Send+Sync,);
implement_method!([get_value] UnsafeSendSyncParameter,UnsafeAny,+Send+Sync, downcast_unchecked);