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