extern crate fnv;
extern crate pi_atom;
extern crate pi_gray;
use std::rc::Rc;
use std::any::Any;
use std::sync::Arc;
use std::collections::HashMap;
use futures::future::LocalBoxFuture;
use fnv::FnvHashMap;
use pi_atom::Atom;
use pi_gray::GrayVersion;
pub trait Env {
fn get_attr(&self, _key: Atom) -> Option<GenType> {
None
}
fn set_attr(&self, _key: Atom, _value: GenType) -> Option<GenType> {
None
}
fn remove_attr(&self, _key: Atom) -> Option<GenType> {
None
}
}
pub trait Handler: Send + Sync {
type A;
type B;
type C;
type D;
type E;
type F;
type G;
type H;
type HandleResult;
fn handle(&self, env: Arc<dyn GrayVersion>, func: Atom, args: Args<Self::A, Self::B, Self::C, Self::D, Self::E, Self::F, Self::G, Self::H>) -> LocalBoxFuture<'static, Self::HandleResult>;
}
#[derive(Debug, Clone)]
pub enum GenMapType {
U8KeyMap(FnvHashMap<u8, GenType>),
U16KeyMap(FnvHashMap<u16, GenType>),
U32KeyMap(FnvHashMap<u32, GenType>),
U64KeyMap(FnvHashMap<u64, GenType>),
U128KeyMap(FnvHashMap<u128, GenType>),
USizeKeyMap(FnvHashMap<usize, GenType>),
I8KeyMap(FnvHashMap<i8, GenType>),
I16KeyMap(FnvHashMap<i16, GenType>),
I32KeyMap(FnvHashMap<i32, GenType>),
I64KeyMap(FnvHashMap<i64, GenType>),
I128KeyMap(FnvHashMap<i128, GenType>),
ISizeKeyMap(FnvHashMap<isize, GenType>),
StrKeyMap(HashMap<String, GenType>),
StringKeyMap(HashMap<Atom, GenType>),
BinKeyMap(HashMap<Vec<u8>, GenType>),
PtrKeyMap(FnvHashMap<*const dyn Any, GenType>),
}
#[derive(Debug, Clone)]
pub enum GenType {
Nil,
Bool(bool),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
USize(usize),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
ISize(isize),
F32(f32),
F64(f64),
Str(String),
String(Atom),
Bin(Vec<u8>),
BoxBin(Box<Vec<u8>>),
RcBin(Rc<Vec<u8>>),
ArcBin(Arc<Vec<u8>>),
PtrBin(*const u8),
Pointer(*const dyn Any),
Array(Vec<GenType>),
Map(GenMapType),
Obj(HashMap<Atom, GenType>),
}
#[derive(Debug, Clone)]
pub enum SGenMapType {
U8KeyMap(FnvHashMap<u8, SGenType>),
U16KeyMap(FnvHashMap<u16, SGenType>),
U32KeyMap(FnvHashMap<u32, SGenType>),
U64KeyMap(FnvHashMap<u64, SGenType>),
U128KeyMap(FnvHashMap<u128, SGenType>),
USizeKeyMap(FnvHashMap<usize, SGenType>),
I8KeyMap(FnvHashMap<i8, SGenType>),
I16KeyMap(FnvHashMap<i16, SGenType>),
I32KeyMap(FnvHashMap<i32, SGenType>),
I64KeyMap(FnvHashMap<i64, SGenType>),
I128KeyMap(FnvHashMap<i128, SGenType>),
ISizeKeyMap(FnvHashMap<isize, SGenType>),
StrKeyMap(HashMap<String, SGenType>),
StringKeyMap(HashMap<Atom, SGenType>),
BinKeyMap(HashMap<Vec<u8>, SGenType>),
}
#[derive(Debug, Clone)]
pub enum SGenType {
Nil,
Bool(bool),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
USize(usize),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
ISize(isize),
F32(f32),
F64(f64),
Str(String),
String(Atom),
Bin(Vec<u8>),
BoxBin(Box<Vec<u8>>),
ArcBin(Arc<Vec<u8>>),
Array(Vec<SGenType>),
Map(SGenMapType),
Obj(HashMap<Atom, SGenType>),
}
pub enum Args<A, B, C, D, E, F, G, H> {
NilArgs, OneArgs(A),
TwoArgs(A, B),
ThreeArgs(A, B, C),
FourArgs(A, B, C, D),
FiveArgs(A, B, C, D, E),
SixArgs(A, B, C, D, E, F),
SevenArgs(A, B, C, D, E, F, G),
EightArgs(A, B, C, D, E, F, G, H),
VarArgs(Vec<Box<dyn Any>>), }
impl<A, B, C, D, E, F, G, H> Args<A, B, C, D, E, F, G, H> {
pub fn with(size: usize) -> Self {
if size == 0 {
return Args::NilArgs;
}
Args::VarArgs(Vec::with_capacity(size))
}
pub fn len(&self) -> usize {
match self {
Args::NilArgs => 0,
Args::OneArgs(_) => 1,
Args::TwoArgs(_, _) => 2,
Args::ThreeArgs(_, _, _) => 3,
Args::FourArgs(_, _, _, _) => 4,
Args::FiveArgs(_, _, _, _, _) => 5,
Args::SixArgs(_, _, _, _, _, _) => 6,
Args::SevenArgs(_, _, _, _, _, _, _) => 7,
Args::EightArgs(_, _, _, _, _, _, _, _) => 8,
Args::VarArgs(args) => args.len(),
}
}
pub fn get_ref<T: Any>(&self, index: usize) -> Option<&T> {
if index >= self.len() {
return None;
}
match self {
Args::VarArgs(args) => args[index].downcast_ref(),
_ => None,
}
}
pub fn get_mut<T: Any>(&mut self, index: usize) -> Option<&mut T> {
if index >= self.len() {
return None;
}
match self {
Args::VarArgs(args) => args[index].downcast_mut(),
_ => None,
}
}
pub fn set<T: Any>(&mut self, index: usize, arg: T) -> &mut Self {
if index >= self.len() {
return self;
}
match self {
Args::VarArgs(args) => args[index] = Box::new(arg) as Box<dyn Any>,
_ => (),
}
self
}
pub fn pop<T: Any>(&mut self) -> Option<T> {
match self {
Args::VarArgs(args) => {
match args.pop() {
None => None,
Some(any) => {
match any.downcast::<T>() {
Err(_) => None,
Ok(arg) => Some(*arg),
}
},
}
},
_ => None,
}
}
pub fn push<T: Any>(&mut self, arg: T) -> &mut Self {
match self {
Args::VarArgs(args) => args.push(Box::new(arg) as Box<dyn Any>),
_ => (),
}
self
}
pub fn remove<T: Any>(&mut self, index: usize) -> Option<T> {
if index >= self.len() {
return None;
}
match self {
Args::VarArgs(args) => {
match args.remove(index).downcast::<T>() {
Err(_) => None,
Ok(arg) => Some(*arg),
}
},
_ => None,
}
}
pub fn clear(&mut self) -> usize {
let len = self.len();
match self {
Args::VarArgs(args) => args.clear(),
_ => (),
}
len
}
}