1
0
dust/src/built_in_values.rs

205 lines
6.9 KiB
Rust
Raw Normal View History

2024-02-15 20:20:29 +00:00
use std::{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-02-20 04:35:09 +00:00
built_in_functions::{
fs::all_fs_functions, io::all_io_functions, json::json_functions, str::string_functions,
Callable,
},
2024-02-15 20:20:29 +00:00
BuiltInFunction, EnumInstance, Function, Identifier, List, Map, 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();
2024-02-20 04:35:09 +00:00
static IO: OnceLock<Value> = OnceLock::new();
2024-01-01 12:46:47 +00:00
static JSON: OnceLock<Value> = OnceLock::new();
2024-02-15 15:33:25 +00:00
static NONE: OnceLock<Value> = OnceLock::new();
2024-02-15 20:20:29 +00:00
static RANDOM: OnceLock<Value> = OnceLock::new();
static STR: OnceLock<Value> = OnceLock::new();
2024-01-01 10:20:11 +00:00
2024-01-30 23:13:30 +00:00
/// Returns the entire built-in value API.
pub fn all_built_in_values() -> impl Iterator<Item = BuiltInValue> {
all()
}
2024-01-30 23:13:30 +00:00
/// A variable with a hard-coded key that is globally available.
#[derive(Sequence, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
2024-01-01 10:20:11 +00:00
pub enum BuiltInValue {
2024-01-30 23:13:30 +00:00
/// The arguments used to launch the current program.
2024-01-01 10:20:11 +00:00
Args,
2024-01-30 23:13:30 +00:00
/// Create an error if two values are not equal.
2024-01-01 10:20:11 +00:00
AssertEqual,
2024-01-30 23:13:30 +00:00
/// File system tools.
2024-01-01 12:46:47 +00:00
Fs,
2024-01-30 23:13:30 +00:00
2024-02-20 04:35:09 +00:00
/// Input and output tools.
Io,
2024-01-30 23:13:30 +00:00
/// JSON format tools.
2024-01-01 12:46:47 +00:00
Json,
2024-01-30 23:13:30 +00:00
/// Get the length of a collection.
2024-01-01 10:20:11 +00:00
Length,
2024-01-30 23:13:30 +00:00
2024-02-15 15:33:25 +00:00
/// The absence of a value.
None,
2024-01-30 23:13:30 +00:00
/// Print a value to stdout.
2024-01-01 10:20:11 +00:00
Output,
2024-01-30 23:13:30 +00:00
/// Random value generators.
2024-01-01 10:20:11 +00:00
Random,
2024-01-30 23:13:30 +00:00
/// String utilities.
Str,
2024-01-01 10:20:11 +00:00
}
impl BuiltInValue {
2024-01-30 23:13:30 +00:00
/// Returns the hard-coded key used to identify the value.
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",
2024-02-20 04:35:09 +00:00
BuiltInValue::Io => "io",
2024-01-06 13:11:09 +00:00
BuiltInValue::Json => "json",
2024-01-30 23:13:30 +00:00
BuiltInValue::Length => BuiltInFunction::Length.name(),
2024-02-15 15:33:25 +00:00
BuiltInValue::None => "None",
2024-01-06 13:11:09 +00:00
BuiltInValue::Output => "output",
BuiltInValue::Random => "random",
BuiltInValue::Str => "str",
2024-01-06 13:11:09 +00:00
}
}
2024-01-30 23:13:30 +00:00
/// Returns a brief description of the value's features.
///
/// This is used by the shell when suggesting completions.
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.",
2024-02-20 04:35:09 +00:00
BuiltInValue::Io => "Input/output tools.",
2024-01-28 17:04:33 +00:00
BuiltInValue::Json => "JSON formatting tools.",
BuiltInValue::Length => BuiltInFunction::Length.description(),
2024-02-15 15:33:25 +00:00
BuiltInValue::None => "The absence of a value.",
2024-01-28 17:04:33 +00:00
BuiltInValue::Output => "output",
BuiltInValue::Random => "random",
BuiltInValue::Str => "string",
2024-01-28 17:04:33 +00:00
}
}
2024-01-30 23:13:30 +00:00
/// Returns the value by creating it or, if it has already been accessed, retrieving it from its
/// [OnceLock][].
2024-02-15 21:02:27 +00:00
pub fn get(&self) -> Value {
2024-01-01 10:20:11 +00:00
match self {
2024-02-15 21:02:27 +00:00
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
2024-02-15 21:02:27 +00:00
Value::List(List::with_items(args))
})
.clone(),
2024-01-01 10:20:11 +00:00
BuiltInValue::AssertEqual => {
2024-02-15 21:02:27 +00:00
Value::Function(Function::BuiltIn(BuiltInFunction::AssertEqual))
2024-01-01 10:20:11 +00:00
}
2024-02-20 04:35:09 +00:00
BuiltInValue::Io => IO
.get_or_init(|| {
let mut io_map = Map::new();
for io_function in all_io_functions() {
let key = io_function.name();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Io(io_function)));
io_map.set(Identifier::new(key), value);
}
Value::Map(io_map)
})
.clone(),
2024-02-15 21:02:27 +00:00
BuiltInValue::Fs => FS
.get_or_init(|| {
let mut fs_map = Map::new();
2024-02-20 04:35:09 +00:00
for fs_function in all_fs_functions() {
2024-02-15 21:02:27 +00:00
let key = fs_function.name();
let value =
Value::Function(Function::BuiltIn(BuiltInFunction::Fs(fs_function)));
fs_map.set(Identifier::new(key), value);
}
Value::Map(fs_map)
})
.clone(),
BuiltInValue::Json => JSON
.get_or_init(|| {
let mut json_map = Map::new();
for json_function in json_functions() {
let key = json_function.name();
let value = Value::Function(Function::BuiltIn(BuiltInFunction::Json(
json_function,
)));
json_map.set(Identifier::new(key), value);
}
Value::Map(json_map)
})
.clone(),
BuiltInValue::Length => Value::Function(Function::BuiltIn(BuiltInFunction::Length)),
BuiltInValue::None => NONE
.get_or_init(|| {
Value::Enum(EnumInstance::new(
Identifier::new("Option"),
Identifier::new("None"),
None,
))
})
.clone(),
BuiltInValue::Output => Value::Function(Function::BuiltIn(BuiltInFunction::Output)),
BuiltInValue::Random => RANDOM
.get_or_init(|| {
let mut random_map = Map::new();
for built_in_function in [
BuiltInFunction::RandomBoolean,
BuiltInFunction::RandomFloat,
BuiltInFunction::RandomFrom,
BuiltInFunction::RandomInteger,
] {
let identifier = Identifier::new(built_in_function.name());
let value = Value::Function(Function::BuiltIn(built_in_function));
random_map.set(identifier, value);
}
Value::Map(random_map)
})
.clone(),
BuiltInValue::Str => STR
.get_or_init(|| {
let mut str_map = Map::new();
for string_function in string_functions() {
let identifier = Identifier::new(string_function.name());
let value = Value::Function(Function::BuiltIn(BuiltInFunction::String(
string_function,
)));
str_map.set(identifier, value);
}
Value::Map(str_map)
})
.clone(),
2024-01-01 10:20:11 +00:00
}
}
}