1
0
dust/src/abstract_tree/built_in_value.rs

181 lines
6.4 KiB
Rust
Raw Normal View History

2024-01-17 15:21:00 +00:00
use std::{collections::BTreeMap, env::args, sync::OnceLock};
2024-01-01 10:20:11 +00:00
use enum_iterator::{all, Sequence};
2024-01-01 10:20:11 +00:00
use serde::{Deserialize, Serialize};
2024-01-01 13:52:25 +00:00
use crate::{
2024-01-30 19:11:18 +00:00
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
2024-01-26 22:14:57 +00:00
AbstractTree, BuiltInFunction, Format, Function, List, Map, Result, SyntaxNode, Type, Value,
2024-01-01 13:52:25 +00:00
};
2024-01-01 10:20:11 +00:00
static ARGS: OnceLock<Value> = OnceLock::new();
2024-01-01 12:46:47 +00:00
static FS: OnceLock<Value> = OnceLock::new();
static JSON: OnceLock<Value> = OnceLock::new();
2024-01-01 10:20:11 +00:00
static RANDOM: OnceLock<Value> = OnceLock::new();
2024-01-01 13:52:25 +00:00
static STRING: OnceLock<Value> = OnceLock::new();
2024-01-01 10:20:11 +00:00
pub fn built_in_values() -> impl Iterator<Item = BuiltInValue> {
all()
}
#[derive(Sequence, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
2024-01-01 10:20:11 +00:00
pub enum BuiltInValue {
Args,
AssertEqual,
2024-01-01 12:46:47 +00:00
Fs,
Json,
2024-01-01 10:20:11 +00:00
Length,
Output,
Random,
Str,
2024-01-01 10:20:11 +00:00
}
impl BuiltInValue {
2024-01-28 17:04:33 +00:00
pub fn name(&self) -> &'static str {
2024-01-06 13:11:09 +00:00
match self {
BuiltInValue::Args => "args",
BuiltInValue::AssertEqual => "assert_equal",
BuiltInValue::Fs => "fs",
BuiltInValue::Json => "json",
BuiltInValue::Length => "length",
BuiltInValue::Output => "output",
BuiltInValue::Random => "random",
BuiltInValue::Str => "str",
2024-01-06 13:11:09 +00:00
}
}
2024-01-28 17:04:33 +00:00
pub fn description(&self) -> &'static str {
match self {
BuiltInValue::Args => "The command line arguments sent to this program.",
BuiltInValue::AssertEqual => "Error if the two values are not equal.",
BuiltInValue::Fs => "File and directory tools.",
BuiltInValue::Json => "JSON formatting tools.",
BuiltInValue::Length => BuiltInFunction::Length.description(),
BuiltInValue::Output => "output",
BuiltInValue::Random => "random",
BuiltInValue::Str => "string",
2024-01-28 17:04:33 +00:00
}
}
pub fn r#type(&self) -> Type {
2024-01-01 10:20:11 +00:00
match self {
2024-01-01 14:39:59 +00:00
BuiltInValue::Args => Type::list(Type::String),
2024-01-01 10:20:11 +00:00
BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(),
2024-01-06 08:47:54 +00:00
BuiltInValue::Fs => Type::Map(None),
BuiltInValue::Json => Type::Map(None),
2024-01-01 10:20:11 +00:00
BuiltInValue::Length => BuiltInFunction::Length.r#type(),
BuiltInValue::Output => BuiltInFunction::Output.r#type(),
2024-01-06 08:47:54 +00:00
BuiltInValue::Random => Type::Map(None),
BuiltInValue::Str => Type::Map(None),
2024-01-01 10:20:11 +00:00
}
}
pub fn get(&self) -> &Value {
2024-01-01 10:20:11 +00:00
match self {
BuiltInValue::Args => ARGS.get_or_init(|| {
let args = args().map(|arg| Value::string(arg.to_string())).collect();
2024-01-01 10:20:11 +00:00
Value::List(List::with_items(args))
}),
BuiltInValue::AssertEqual => {
&Value::Function(Function::BuiltIn(BuiltInFunction::AssertEqual))
}
2024-01-01 12:46:47 +00:00
BuiltInValue::Fs => FS.get_or_init(|| {
2024-01-30 04:18:09 +00:00
let mut fs_context = BTreeMap::new();
2024-01-01 12:46:47 +00:00
2024-01-30 04:18:09 +00:00
for fs_function in fs_functions() {
let key = fs_function.name().to_string();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Fs(fs_function)));
let r#type = value.r#type();
2024-01-01 12:46:47 +00:00
2024-01-30 04:18:09 +00:00
fs_context.insert(key, (value, r#type));
}
Value::Map(Map::with_variables(fs_context))
2024-01-01 12:46:47 +00:00
}),
BuiltInValue::Json => JSON.get_or_init(|| {
2024-01-26 22:14:57 +00:00
let mut json_context = BTreeMap::new();
2024-01-01 12:46:47 +00:00
2024-01-26 22:14:57 +00:00
for json_function in json_functions() {
let key = json_function.name().to_string();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Json(json_function)));
let r#type = value.r#type();
json_context.insert(key, (value, r#type));
}
2024-01-01 12:46:47 +00:00
2024-01-26 22:14:57 +00:00
Value::Map(Map::with_variables(json_context))
2024-01-01 12:46:47 +00:00
}),
2024-01-01 10:20:11 +00:00
BuiltInValue::Length => &Value::Function(Function::BuiltIn(BuiltInFunction::Length)),
BuiltInValue::Output => &Value::Function(Function::BuiltIn(BuiltInFunction::Output)),
BuiltInValue::Random => RANDOM.get_or_init(|| {
2024-01-17 15:21:00 +00:00
let mut random_context = BTreeMap::new();
for built_in_function in [
BuiltInFunction::RandomBoolean,
BuiltInFunction::RandomFloat,
BuiltInFunction::RandomFrom,
BuiltInFunction::RandomInteger,
] {
let key = built_in_function.name().to_string();
2024-01-25 09:19:45 +00:00
let value = Value::Function(Function::BuiltIn(built_in_function));
let r#type = built_in_function.r#type();
2024-01-17 15:21:00 +00:00
random_context.insert(key, (value, r#type));
2024-01-01 10:20:11 +00:00
}
2024-01-17 15:21:00 +00:00
Value::Map(Map::with_variables(random_context))
2024-01-01 10:20:11 +00:00
}),
BuiltInValue::Str => STRING.get_or_init(|| {
2024-01-17 15:21:00 +00:00
let mut string_context = BTreeMap::new();
2024-01-01 13:52:25 +00:00
2024-01-17 15:21:00 +00:00
for string_function in string_functions() {
let key = string_function.name().to_string();
let value = Value::Function(Function::BuiltIn(BuiltInFunction::String(
string_function,
)));
let r#type = string_function.r#type();
2024-01-01 13:52:25 +00:00
2024-01-17 15:21:00 +00:00
string_context.insert(key, (value, r#type));
2024-01-01 13:52:25 +00:00
}
2024-01-17 15:21:00 +00:00
Value::Map(Map::with_variables(string_context))
2024-01-01 13:52:25 +00:00
}),
2024-01-01 10:20:11 +00:00
}
}
}
impl AbstractTree for BuiltInValue {
2024-01-10 20:03:52 +00:00
fn from_syntax(node: SyntaxNode, _source: &str, _context: &Map) -> Result<Self> {
2024-01-01 10:20:11 +00:00
let built_in_value = match node.kind() {
"args" => BuiltInValue::Args,
"assert_equal" => BuiltInValue::AssertEqual,
2024-01-01 12:46:47 +00:00
"fs" => BuiltInValue::Fs,
"json" => BuiltInValue::Json,
2024-01-01 10:20:11 +00:00
"length" => BuiltInValue::Length,
"output" => BuiltInValue::Output,
"random" => BuiltInValue::Random,
"str" => BuiltInValue::Str,
2024-01-01 10:20:11 +00:00
_ => todo!(),
};
Ok(built_in_value)
}
fn run(&self, _source: &str, _context: &Map) -> Result<Value> {
Ok(self.get().clone())
}
fn expected_type(&self, _context: &Map) -> Result<Type> {
Ok(self.r#type())
}
}
2024-01-06 10:00:36 +00:00
2024-01-06 13:11:09 +00:00
impl Format for BuiltInValue {
2024-01-06 13:53:31 +00:00
fn format(&self, output: &mut String, _indent_level: u8) {
2024-01-06 13:11:09 +00:00
output.push_str(&self.get().to_string());
2024-01-06 10:00:36 +00:00
}
}