use super::*;
use std::env;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::process;
pub struct OS;
impl Module for OS {
async fn load(&self, state: &mut State) -> Result<(), LuaError> {
let module = state.lua.create_table()?;
module.set(
"exec",
state.lua.create_async_function(
|lua, (name, args): (String, Vec<String>)| async move {
let exec = match urs::misc::search_in_path(&name) {
Some(p) => p,
None => return Err(LuaError::runtime("Executable not found")),
};
let output = match process::Command::new(exec).args(args).output().await {
Ok(o) => o,
Err(e) => return Err(LuaError::external(Arc::new(e))),
};
match String::from_utf8(output.stdout) {
Ok(string) => Ok(string.trim().into_lua(&lua)?),
Err(e) => Err(LuaError::external(Arc::new(e))),
}
},
)?,
)?;
module.set(
"get_pid",
state
.lua
.create_function(|_, _: ()| Ok(std::process::id()))?,
)?;
module.set(
"get_env",
state
.lua
.create_function(|lua, name: String| match env::var(name) {
Ok(v) => Ok(v.into_lua(lua)?),
Err(_) => Ok(LuaValue::Nil),
})?,
)?;
module.set(
"set_env",
state
.lua
.create_function(|_, (name, value): (String, String)| {
env::set_var(name, value);
Ok(())
})?,
)?;
module.set(
"current_exe",
state
.lua
.create_function(|lua, _: ()| match env::current_exe() {
Ok(p) => Ok(p.into_lua(lua)?),
Err(e) => Err(LuaError::external(Arc::new(e))),
})?,
)?;
module.set(
"get_cwd",
state
.lua
.create_function(|lua, _: ()| match env::current_dir() {
Ok(p) => Ok(p.into_lua(lua)?),
Err(_) => Ok(LuaValue::Nil),
})?,
)?;
module.set(
"set_cwd",
state.lua.create_function(|_, p: PathBuf| {
env::set_current_dir(p)?;
Ok(())
})?,
)?;
create_module(&state.lua, "autosway.os", module)?;
Ok(())
}
}