use dupe::Dupe;
use crate::typing::callable_param::ParamIsRequired;
use crate::typing::macro_support::unpack_args_item_ty;
use crate::typing::macro_support::unpack_kwargs_value_ty;
use crate::typing::ParamSpec;
use crate::typing::Ty;
use crate::util::arc_str::ArcStr;
use crate::values::FrozenValue;
pub enum NativeCallableParamDefaultValue {
Value(FrozenValue),
Optional,
}
pub struct NativeCallableParam {
pub name: &'static str,
pub ty: Ty,
pub required: Option<NativeCallableParamDefaultValue>,
}
impl NativeCallableParam {
pub fn args(name: &'static str, param_ty: Ty) -> NativeCallableParam {
NativeCallableParam {
name,
ty: unpack_args_item_ty(param_ty),
required: None,
}
}
pub fn kwargs(name: &'static str, param_ty: Ty) -> NativeCallableParam {
NativeCallableParam {
name,
ty: unpack_kwargs_value_ty(param_ty),
required: None,
}
}
fn is_required(&self) -> ParamIsRequired {
match self.required {
None => ParamIsRequired::Yes,
Some(_) => ParamIsRequired::No,
}
}
}
pub struct NativeCallableParamSpec {
pub pos_only: Vec<NativeCallableParam>,
pub pos_or_named: Vec<NativeCallableParam>,
pub args: Option<NativeCallableParam>,
pub named_only: Vec<NativeCallableParam>,
pub kwargs: Option<NativeCallableParam>,
}
impl NativeCallableParamSpec {
pub fn for_arguments() -> NativeCallableParamSpec {
NativeCallableParamSpec {
pos_only: Vec::new(),
pos_or_named: Vec::new(),
args: Some(NativeCallableParam::args("args", Ty::any())),
named_only: Vec::new(),
kwargs: Some(NativeCallableParam::kwargs("kwargs", Ty::any())),
}
}
pub(crate) fn param_spec(&self) -> ParamSpec {
ParamSpec::new_parts(
self.pos_only.iter().map(|p| (p.is_required(), p.ty.dupe())),
self.pos_or_named
.iter()
.map(|p| (ArcStr::new_static(p.name), p.is_required(), p.ty.dupe())),
self.args.as_ref().map(|p| p.ty.dupe()),
self.named_only
.iter()
.map(|p| (ArcStr::new_static(p.name), p.is_required(), p.ty.dupe())),
self.kwargs.as_ref().map(|p| p.ty.dupe()),
)
.unwrap()
}
}