Implement string functions
This commit is contained in:
parent
c2d919957e
commit
ab4c8922b1
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
built_in_functions::{string_functions, StringFunction},
|
||||
AbstractTree, BuiltInFunction, Function, List, Map, Result, Type, Value,
|
||||
built_in_functions::string_functions, AbstractTree, BuiltInFunction, Function, List, Map,
|
||||
Result, Type, Value,
|
||||
};
|
||||
|
||||
static ARGS: OnceLock<Value> = OnceLock::new();
|
||||
@ -29,7 +29,7 @@ pub enum BuiltInValue {
|
||||
impl BuiltInValue {
|
||||
fn r#type(&self) -> Type {
|
||||
match self {
|
||||
BuiltInValue::Args => Type::list_of(Type::String),
|
||||
BuiltInValue::Args => Type::list(Type::String),
|
||||
BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(),
|
||||
BuiltInValue::Fs => Type::Map,
|
||||
BuiltInValue::Json => Type::Map,
|
||||
@ -106,7 +106,7 @@ impl BuiltInValue {
|
||||
{
|
||||
let mut variables = string_context.variables_mut().unwrap();
|
||||
|
||||
for string_function in [StringFunction::AsBytes] {
|
||||
for string_function in string_functions() {
|
||||
let key = string_function.name().to_string();
|
||||
let value = Value::Function(Function::BuiltIn(BuiltInFunction::String(
|
||||
string_function,
|
||||
|
@ -69,7 +69,7 @@ pub enum Type {
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn list_of(item_type: Type) -> Self {
|
||||
pub fn list(item_type: Type) -> Self {
|
||||
Type::List(Box::new(item_type))
|
||||
}
|
||||
|
||||
@ -80,6 +80,10 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn option(optional_type: Type) -> Self {
|
||||
Type::Option(Box::new(optional_type))
|
||||
}
|
||||
|
||||
pub fn check(&self, other: &Type) -> Result<()> {
|
||||
match (self, other) {
|
||||
(Type::Any, _)
|
||||
@ -257,10 +261,10 @@ impl Display for Type {
|
||||
} => {
|
||||
write!(f, "(")?;
|
||||
|
||||
for parameter_type in parameter_types {
|
||||
for (index, parameter_type) in parameter_types.iter().enumerate() {
|
||||
write!(f, "{parameter_type}")?;
|
||||
|
||||
if parameter_type != parameter_types.last().unwrap() {
|
||||
if index != parameter_types.len() - 1 {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
}
|
||||
|
@ -43,68 +43,104 @@ impl StringFunction {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
StringFunction::AsBytes => "as_bytes",
|
||||
StringFunction::EndsWith => todo!(),
|
||||
StringFunction::Find => todo!(),
|
||||
StringFunction::IsAscii => todo!(),
|
||||
StringFunction::IsEmpty => todo!(),
|
||||
StringFunction::Lines => todo!(),
|
||||
StringFunction::Matches => todo!(),
|
||||
StringFunction::Split => todo!(),
|
||||
StringFunction::SplitAt => todo!(),
|
||||
StringFunction::SplitInclusive => todo!(),
|
||||
StringFunction::SplitN => todo!(),
|
||||
StringFunction::SplitOnce => todo!(),
|
||||
StringFunction::SplitTerminator => todo!(),
|
||||
StringFunction::SplitWhitespace => todo!(),
|
||||
StringFunction::StartsWith => todo!(),
|
||||
StringFunction::StripPrefix => todo!(),
|
||||
StringFunction::ToLowercase => todo!(),
|
||||
StringFunction::ToUppercase => todo!(),
|
||||
StringFunction::Trim => todo!(),
|
||||
StringFunction::TrimEnd => todo!(),
|
||||
StringFunction::TrimEndMatches => todo!(),
|
||||
StringFunction::TrimLeft => todo!(),
|
||||
StringFunction::TrimLeftMatches => todo!(),
|
||||
StringFunction::TrimMatches => todo!(),
|
||||
StringFunction::TrimRight => todo!(),
|
||||
StringFunction::TrimRightMatches => todo!(),
|
||||
StringFunction::TrimStart => todo!(),
|
||||
StringFunction::TrimStartMatches => todo!(),
|
||||
StringFunction::EndsWith => "ends_with",
|
||||
StringFunction::Find => "find",
|
||||
StringFunction::IsAscii => "is_ascii",
|
||||
StringFunction::IsEmpty => "is_empty",
|
||||
StringFunction::Lines => "lines",
|
||||
StringFunction::Matches => "matches",
|
||||
StringFunction::Split => "split",
|
||||
StringFunction::SplitAt => "split_at",
|
||||
StringFunction::SplitInclusive => "split_inclusive",
|
||||
StringFunction::SplitN => "split_n",
|
||||
StringFunction::SplitOnce => "split_once",
|
||||
StringFunction::SplitTerminator => "split_terminator",
|
||||
StringFunction::SplitWhitespace => "split_whitespace",
|
||||
StringFunction::StartsWith => "starts_with",
|
||||
StringFunction::StripPrefix => "strip_prefix",
|
||||
StringFunction::ToLowercase => "to_lowercase",
|
||||
StringFunction::ToUppercase => "to_uppercase",
|
||||
StringFunction::Trim => "trim",
|
||||
StringFunction::TrimEnd => "trim_end",
|
||||
StringFunction::TrimEndMatches => "trim_end_matches",
|
||||
StringFunction::TrimLeft => "trim_left",
|
||||
StringFunction::TrimLeftMatches => "trim_left_matches",
|
||||
StringFunction::TrimMatches => "trim_matches",
|
||||
StringFunction::TrimRight => "trim_right",
|
||||
StringFunction::TrimRightMatches => "trim_right_matches",
|
||||
StringFunction::TrimStart => "trim_start",
|
||||
StringFunction::TrimStartMatches => "trim_start_matches",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r#type(&self) -> Type {
|
||||
match self {
|
||||
StringFunction::AsBytes => {
|
||||
Type::function(vec![Type::String], Type::list_of(Type::Integer))
|
||||
Type::function(vec![Type::String], Type::list(Type::Integer))
|
||||
}
|
||||
StringFunction::EndsWith => {
|
||||
Type::function(vec![Type::String, Type::String], Type::Boolean)
|
||||
}
|
||||
StringFunction::Find => Type::function(
|
||||
vec![Type::String, Type::String],
|
||||
Type::option(Type::Integer),
|
||||
),
|
||||
StringFunction::IsAscii => Type::function(vec![Type::String], Type::Boolean),
|
||||
StringFunction::IsEmpty => Type::function(vec![Type::String], Type::Boolean),
|
||||
StringFunction::Lines => Type::function(vec![Type::String], Type::list(Type::String)),
|
||||
StringFunction::Matches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::Split => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::SplitAt => {
|
||||
Type::function(vec![Type::String, Type::Integer], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::SplitInclusive => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::SplitN => Type::function(
|
||||
vec![Type::String, Type::Integer, Type::String],
|
||||
Type::list(Type::String),
|
||||
),
|
||||
StringFunction::SplitOnce => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::SplitTerminator => {
|
||||
Type::function(vec![Type::String, Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::SplitWhitespace => {
|
||||
Type::function(vec![Type::String], Type::list(Type::String))
|
||||
}
|
||||
StringFunction::StartsWith => {
|
||||
Type::function(vec![Type::String, Type::String], Type::Boolean)
|
||||
}
|
||||
StringFunction::StripPrefix => {
|
||||
Type::function(vec![Type::String, Type::String], Type::option(Type::String))
|
||||
}
|
||||
StringFunction::ToLowercase => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::ToUppercase => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::Trim => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimEnd => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimEndMatches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::String)
|
||||
}
|
||||
StringFunction::TrimLeft => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimLeftMatches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::String)
|
||||
}
|
||||
StringFunction::TrimMatches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::String)
|
||||
}
|
||||
StringFunction::TrimRight => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimRightMatches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::String)
|
||||
}
|
||||
StringFunction::TrimStart => Type::function(vec![Type::String], Type::String),
|
||||
StringFunction::TrimStartMatches => {
|
||||
Type::function(vec![Type::String, Type::String], Type::String)
|
||||
}
|
||||
StringFunction::EndsWith => todo!(),
|
||||
StringFunction::Find => todo!(),
|
||||
StringFunction::IsAscii => todo!(),
|
||||
StringFunction::IsEmpty => todo!(),
|
||||
StringFunction::Lines => todo!(),
|
||||
StringFunction::Matches => todo!(),
|
||||
StringFunction::Split => todo!(),
|
||||
StringFunction::SplitAt => todo!(),
|
||||
StringFunction::SplitInclusive => todo!(),
|
||||
StringFunction::SplitN => todo!(),
|
||||
StringFunction::SplitOnce => todo!(),
|
||||
StringFunction::SplitTerminator => todo!(),
|
||||
StringFunction::SplitWhitespace => todo!(),
|
||||
StringFunction::StartsWith => todo!(),
|
||||
StringFunction::StripPrefix => todo!(),
|
||||
StringFunction::ToLowercase => todo!(),
|
||||
StringFunction::ToUppercase => todo!(),
|
||||
StringFunction::Trim => todo!(),
|
||||
StringFunction::TrimEnd => todo!(),
|
||||
StringFunction::TrimEndMatches => todo!(),
|
||||
StringFunction::TrimLeft => todo!(),
|
||||
StringFunction::TrimLeftMatches => todo!(),
|
||||
StringFunction::TrimMatches => todo!(),
|
||||
StringFunction::TrimRight => todo!(),
|
||||
StringFunction::TrimRightMatches => todo!(),
|
||||
StringFunction::TrimStart => todo!(),
|
||||
StringFunction::TrimStartMatches => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +174,13 @@ impl StringFunction {
|
||||
StringFunction::StripPrefix => todo!(),
|
||||
StringFunction::ToLowercase => todo!(),
|
||||
StringFunction::ToUppercase => todo!(),
|
||||
StringFunction::Trim => todo!(),
|
||||
StringFunction::Trim => {
|
||||
Error::expect_argument_amount(self.name(), 1, arguments.len())?;
|
||||
|
||||
let trimmed = arguments.first().unwrap().as_string()?.trim().to_string();
|
||||
|
||||
Ok(Value::String(trimmed))
|
||||
}
|
||||
StringFunction::TrimEnd => todo!(),
|
||||
StringFunction::TrimEndMatches => todo!(),
|
||||
StringFunction::TrimLeft => todo!(),
|
||||
|
Loading…
Reference in New Issue
Block a user