112 lines
2.9 KiB
Rust
112 lines
2.9 KiB
Rust
use std::{
|
|
fs::{read_dir, read_to_string, write, File},
|
|
io::Write as IoWrite,
|
|
path::PathBuf,
|
|
};
|
|
|
|
use crate::{BuiltInFunction, List, Map, Result, Type, Value};
|
|
|
|
pub struct Read;
|
|
|
|
impl BuiltInFunction for Read {
|
|
fn name(&self) -> &'static str {
|
|
"read"
|
|
}
|
|
|
|
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
|
|
let path_string = arguments.first().unwrap_or_default().as_string()?;
|
|
let path = PathBuf::from(path_string);
|
|
|
|
if path.is_dir() {
|
|
let files = List::new();
|
|
|
|
for entry in read_dir(&path)? {
|
|
let entry = entry?;
|
|
let file_data = Map::new();
|
|
|
|
let name = entry.file_name().to_string_lossy().to_string();
|
|
let metadata = entry.metadata()?;
|
|
let created = metadata.created()?.elapsed()?.as_secs() as i64;
|
|
let modified = metadata.modified()?.elapsed()?.as_secs() as i64;
|
|
|
|
file_data.set("name".to_string(), Value::String(name), None)?;
|
|
file_data.set("created".to_string(), Value::Integer(created), None)?;
|
|
file_data.set("modified".to_string(), Value::Integer(modified), None)?;
|
|
|
|
files.items_mut().push(Value::Map(file_data));
|
|
}
|
|
|
|
return Ok(Value::List(files));
|
|
}
|
|
|
|
let file_content = read_to_string(path)?;
|
|
|
|
Ok(Value::String(file_content))
|
|
}
|
|
|
|
fn r#type(&self) -> Type {
|
|
Type::Function {
|
|
parameter_types: vec![Type::String],
|
|
return_type: Box::new(Type::String),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Write;
|
|
|
|
impl BuiltInFunction for Write {
|
|
fn name(&self) -> &'static str {
|
|
"write"
|
|
}
|
|
|
|
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
|
|
let file_content = arguments.first().unwrap_or_default().as_string()?;
|
|
let path = arguments.get(1).unwrap_or_default().as_string()?;
|
|
|
|
write(path, file_content)?;
|
|
|
|
Ok(Value::Option(None))
|
|
}
|
|
|
|
fn r#type(&self) -> Type {
|
|
Type::Function {
|
|
parameter_types: vec![Type::String],
|
|
return_type: Box::new(Type::None),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Append;
|
|
|
|
impl BuiltInFunction for Append {
|
|
fn name(&self) -> &'static str {
|
|
"append"
|
|
}
|
|
|
|
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
|
|
let file_content = arguments
|
|
.first()
|
|
.unwrap_or(&Value::Option(None))
|
|
.as_string()?;
|
|
let path = arguments
|
|
.get(1)
|
|
.unwrap_or(&Value::Option(None))
|
|
.as_string()?;
|
|
|
|
File::options()
|
|
.append(true)
|
|
.create(true)
|
|
.open(path)?
|
|
.write_all(file_content.as_bytes())?;
|
|
|
|
Ok(Value::Option(None))
|
|
}
|
|
|
|
fn r#type(&self) -> Type {
|
|
Type::Function {
|
|
parameter_types: vec![Type::String, Type::String],
|
|
return_type: Box::new(Type::None),
|
|
}
|
|
}
|
|
}
|