use anyhow::{anyhow, Result};
use easy_error::Error as BundError;
use rust_dynamic::value::Value;
use rust_multistackvm::multistackvm::VM;
use super::helpers::{pull, push, require_depth, value_to_string};
pub fn register(vm: &mut VM) -> Result<()> {
vm.register_inline("ink.fs.read".to_string(), ink_fs_read)
.map_err(|e| anyhow!("register ink.fs.read: {e}"))?;
vm.register_inline("ink.fs.write".to_string(), ink_fs_write)
.map_err(|e| anyhow!("register ink.fs.write: {e}"))?;
Ok(())
}
fn to_bund_err(e: anyhow::Error) -> BundError {
easy_error::err_msg(e.to_string())
}
fn ink_fs_read(vm: &mut VM) -> std::result::Result<&mut VM, BundError> {
do_ink_fs_read(vm).map_err(to_bund_err)
}
fn do_ink_fs_read(vm: &mut VM) -> Result<&mut VM> {
let tag = "ink.fs.read";
require_depth(vm, 1, tag)?;
let path = value_to_string(pull(vm, tag)?, "path", tag)?;
let bytes = std::fs::read(&path)
.map_err(|e| anyhow!("{tag} `{path}`: {e}"))?;
let s = String::from_utf8(bytes)
.map_err(|e| anyhow!("{tag} `{path}`: not UTF-8: {e}"))?;
push(vm, Value::from_string(s));
Ok(vm)
}
fn ink_fs_write(vm: &mut VM) -> std::result::Result<&mut VM, BundError> {
do_ink_fs_write(vm).map_err(to_bund_err)
}
fn do_ink_fs_write(vm: &mut VM) -> Result<&mut VM> {
let tag = "ink.fs.write";
require_depth(vm, 2, tag)?;
let content = value_to_string(pull(vm, tag)?, "content", tag)?;
let path = value_to_string(pull(vm, tag)?, "path", tag)?;
std::fs::write(&path, content.as_bytes())
.map_err(|e| anyhow!("{tag} `{path}`: {e}"))?;
Ok(vm)
}