use arrow::datatypes::DataType;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum Volatility {
Immutable,
Stable,
Volatile,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TypeSignature {
Variadic(Vec<DataType>),
VariadicEqual,
VariadicAny,
Uniform(usize, Vec<DataType>),
Exact(Vec<DataType>),
Any(usize),
OneOf(Vec<TypeSignature>),
}
impl TypeSignature {
pub(crate) fn to_string_repr(&self) -> Vec<String> {
match self {
TypeSignature::Variadic(types) => {
vec![format!("{}, ..", Self::join_types(types, "/"))]
}
TypeSignature::Uniform(arg_count, valid_types) => {
vec![std::iter::repeat(Self::join_types(valid_types, "/"))
.take(*arg_count)
.collect::<Vec<String>>()
.join(", ")]
}
TypeSignature::Exact(types) => {
vec![Self::join_types(types, ", ")]
}
TypeSignature::Any(arg_count) => {
vec![std::iter::repeat("Any")
.take(*arg_count)
.collect::<Vec<&str>>()
.join(", ")]
}
TypeSignature::VariadicEqual => vec!["T, .., T".to_string()],
TypeSignature::VariadicAny => vec!["Any, .., Any".to_string()],
TypeSignature::OneOf(sigs) => {
sigs.iter().flat_map(|s| s.to_string_repr()).collect()
}
}
}
pub(crate) fn join_types<T: std::fmt::Display>(
types: &[T],
delimiter: &str,
) -> String {
types
.iter()
.map(|t| t.to_string())
.collect::<Vec<String>>()
.join(delimiter)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Signature {
pub type_signature: TypeSignature,
pub volatility: Volatility,
}
impl Signature {
pub fn new(type_signature: TypeSignature, volatility: Volatility) -> Self {
Signature {
type_signature,
volatility,
}
}
pub fn variadic(common_types: Vec<DataType>, volatility: Volatility) -> Self {
Self {
type_signature: TypeSignature::Variadic(common_types),
volatility,
}
}
pub fn variadic_equal(volatility: Volatility) -> Self {
Self {
type_signature: TypeSignature::VariadicEqual,
volatility,
}
}
pub fn variadic_any(volatility: Volatility) -> Self {
Self {
type_signature: TypeSignature::VariadicAny,
volatility,
}
}
pub fn uniform(
arg_count: usize,
valid_types: Vec<DataType>,
volatility: Volatility,
) -> Self {
Self {
type_signature: TypeSignature::Uniform(arg_count, valid_types),
volatility,
}
}
pub fn exact(exact_types: Vec<DataType>, volatility: Volatility) -> Self {
Signature {
type_signature: TypeSignature::Exact(exact_types),
volatility,
}
}
pub fn any(arg_count: usize, volatility: Volatility) -> Self {
Signature {
type_signature: TypeSignature::Any(arg_count),
volatility,
}
}
pub fn one_of(type_signatures: Vec<TypeSignature>, volatility: Volatility) -> Self {
Signature {
type_signature: TypeSignature::OneOf(type_signatures),
volatility,
}
}
}