use std::any::TypeId;
use anyhow::bail;
use crate::func::def::{FunctionDef, ParameterBindingProvider, Parameters};
use crate::types::array::Array;
use crate::types::matcher::{AnyMatcher, ArrayMatcher, ExactMatcher, MapMatcher};
use crate::types::{Type, INT, STRING, VARIANT};
#[derive(Default, Clone)]
pub struct GetArray;
impl FunctionDef for GetArray {
fn name(&self) -> &'static str {
"get"
}
fn parameters(&self) -> Parameters {
Parameters::new()
.with("array", ArrayMatcher::default())
.with("index", ExactMatcher::of(INT))
}
fn return_type(&self, bindings: &dyn ParameterBindingProvider) -> anyhow::Result<Type> {
match bindings.get_by_name("array")?.typ() {
Type::Array(arr) => Ok((*arr.element_type).clone()),
_ => bail!("array parameter must be an array"),
}
}
fn type_id(&self) -> TypeId {
TypeId::of::<Self>()
}
}
#[derive(Default, Clone)]
pub struct ArrayVariantGet;
impl FunctionDef for ArrayVariantGet {
fn name(&self) -> &'static str {
"array_variant_get"
}
fn parameters(&self) -> Parameters {
Parameters::new()
.with("array", ArrayMatcher::of(ExactMatcher::of(VARIANT)))
.with("path", ExactMatcher::of(STRING))
}
fn return_type(&self, _bindings: &dyn ParameterBindingProvider) -> anyhow::Result<Type> {
Ok(Array::new(VARIANT).into())
}
fn type_id(&self) -> TypeId {
TypeId::of::<Self>()
}
}
#[derive(Default, Clone)]
pub struct GetMap;
impl FunctionDef for GetMap {
fn name(&self) -> &'static str {
"get"
}
fn parameters(&self) -> Parameters {
Parameters::new()
.with("map", MapMatcher::default())
.with("key", AnyMatcher::default())
}
fn return_type(&self, bindings: &dyn ParameterBindingProvider) -> anyhow::Result<Type> {
match bindings.get_by_name("map")?.typ() {
Type::Map(map) => Ok((*map.value_type).clone()),
_ => bail!("map parameter must be a map"),
}
}
fn type_id(&self) -> TypeId {
TypeId::of::<Self>()
}
}