use std::{io::Write, process::ExitCode};
use vyder::{values, Error, ExpectArity, Module, Span, Value, ValueResult};
pub fn read_file(
arguments: &[ValueResult],
span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
let file_path = arguments.to_vec().expect_exact::<1>(&span)?[0]
.clone()
.expect_non_error()?
.expect::<values::Str>()?
.value;
match std::fs::read_to_string(file_path) {
Ok(file_contents) => Ok((
Value::new_ok_value(
values::Str {
value: file_contents,
}
.into(),
span,
),
None,
)),
Err(_) => Ok((
Value::new_err_value(
values::Str {
value: "failed to read the file".to_string(),
}
.into(),
span,
),
None,
)),
}
}
pub fn write_file(
arguments: &[ValueResult],
span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
let arguments = arguments.to_vec().expect_exact::<2>(&span)?.clone();
let file_path = arguments[0]
.clone()
.expect_non_error()?
.expect::<values::Str>()?
.value;
let file_contents = arguments[1].clone().expect_non_error()?.value.to_string();
let mut file = match std::fs::File::create(file_path) {
Ok(file) => file,
Err(_) => {
return Ok((
Value::new_err_value(
values::Str {
value: "failed to open the file".to_string(),
}
.into(),
span,
),
None,
))
}
};
match file.write_all(file_contents.as_bytes()) {
Ok(_) => Ok((Value::new_ok_value(values::Nil.into(), span), None)),
Err(_) => Ok((
Value::new_err_value(
values::Str {
value: "failed to write to the file".to_string(),
}
.into(),
span,
),
None,
)),
}
}
pub fn input(
arguments: &[ValueResult],
span: Span,
) -> Result<(ValueResult, Option<ExitCode>), Error> {
let prompt = arguments.to_vec().expect_exact::<1>(&span)?[0]
.clone()
.expect_non_error()?
.value
.to_string();
let stdout = &mut std::io::stdout();
let stdin = std::io::stdin();
print!("{}", prompt);
stdout.flush().unwrap();
let mut user_input = String::new();
stdin.read_line(&mut user_input).unwrap();
Ok((
Value::new_ok_value(values::Str { value: user_input }.into(), span),
None,
))
}
pub fn get_module() -> Module {
Module::builder()
.function("read_file", read_file, true)
.function("write_file", write_file, true)
.function("input", input, false)
.build()
}