559a09c5e6
This is unnecessary, Rc already provides all the boxing we need. Change-Id: I08cf0939c48da43f04c847526c7e5dae5336d528 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7749 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org>
96 lines
2.7 KiB
Rust
96 lines
2.7 KiB
Rust
use builtin_macros::builtins;
|
|
use smol_str::SmolStr;
|
|
|
|
use std::{
|
|
env,
|
|
rc::Rc,
|
|
time::{SystemTime, UNIX_EPOCH},
|
|
};
|
|
|
|
use crate::{
|
|
errors::ErrorKind,
|
|
io::FileType,
|
|
value::{NixAttrs, Thunk},
|
|
vm::VM,
|
|
Value,
|
|
};
|
|
|
|
#[builtins]
|
|
mod impure_builtins {
|
|
use super::*;
|
|
use crate::builtins::coerce_value_to_path;
|
|
|
|
#[builtin("getEnv")]
|
|
fn builtin_get_env(_: &mut VM, var: Value) -> Result<Value, ErrorKind> {
|
|
Ok(env::var(var.to_str()?).unwrap_or_else(|_| "".into()).into())
|
|
}
|
|
|
|
#[builtin("pathExists")]
|
|
fn builtin_path_exists(vm: &mut VM, s: Value) -> Result<Value, ErrorKind> {
|
|
let path = coerce_value_to_path(&s, vm)?;
|
|
vm.io().path_exists(path).map(Value::Bool)
|
|
}
|
|
|
|
#[builtin("readDir")]
|
|
fn builtin_read_dir(vm: &mut VM, path: Value) -> Result<Value, ErrorKind> {
|
|
let path = coerce_value_to_path(&path, vm)?;
|
|
|
|
let res = vm.io().read_dir(path)?.into_iter().map(|(name, ftype)| {
|
|
(
|
|
name,
|
|
Value::String(
|
|
SmolStr::new(match ftype {
|
|
FileType::Directory => "directory",
|
|
FileType::Regular => "regular",
|
|
FileType::Symlink => "symlink",
|
|
FileType::Unknown => "unknown",
|
|
})
|
|
.into(),
|
|
),
|
|
)
|
|
});
|
|
|
|
Ok(Value::attrs(NixAttrs::from_iter(res)))
|
|
}
|
|
|
|
#[builtin("readFile")]
|
|
fn builtin_read_file(vm: &mut VM, path: Value) -> Result<Value, ErrorKind> {
|
|
let path = coerce_value_to_path(&path, vm)?;
|
|
vm.io()
|
|
.read_to_string(path)
|
|
.map(|s| Value::String(s.into()))
|
|
}
|
|
}
|
|
|
|
/// Return all impure builtins, that is all builtins which may perform I/O
|
|
/// outside of the VM and so cannot be used in all contexts (e.g. WASM).
|
|
pub fn impure_builtins() -> Vec<(&'static str, Value)> {
|
|
let mut result = impure_builtins::builtins()
|
|
.into_iter()
|
|
.map(super::builtin_tuple)
|
|
.collect::<Vec<_>>();
|
|
|
|
result.push((
|
|
"storeDir",
|
|
Value::Thunk(Thunk::new_suspended_native(Rc::new(
|
|
|vm: &mut VM| match vm.io().store_dir() {
|
|
None => Ok(Value::Null),
|
|
Some(dir) => Ok(Value::String(dir.into())),
|
|
},
|
|
))),
|
|
));
|
|
|
|
// currentTime pins the time at which evaluation was started
|
|
{
|
|
let seconds = match SystemTime::now().duration_since(UNIX_EPOCH) {
|
|
Ok(dur) => dur.as_secs() as i64,
|
|
|
|
// This case is hit if the system time is *before* epoch.
|
|
Err(err) => -(err.duration().as_secs() as i64),
|
|
};
|
|
|
|
result.push(("currentTime", Value::Integer(seconds)));
|
|
}
|
|
|
|
result
|
|
}
|