autosway 0.5.0

Automation program
Documentation
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;

use crate::common::*;
use mlua::prelude::*;
use urs::io::ReadExtra;

mod modules;

pub trait Module {
    fn load(&self, state: &mut State) -> Result<(), mlua::Error>;
}

impl State {
    pub fn setup_lua(&mut self) -> Result<(), LuaError> {
        if let Some(dir) = get_config_dir(ConfigDir::KnifeDir) {
            let s = if let Some(s) = dir.to_str() {
                s
            } else {
                log::log!([error] "Could not extract knife directory");
                return Err(LuaError::RuntimeError(
                    "Could not extract knife directory".to_string(),
                ));
            };

            let code = format!("package.path = package.path..';{}/?/init.lua'", s);
            self.lua.load(code).exec()?
        }

        self.load_module(modules::Core)?;
        self.load_module(modules::Os)?;
        self.load_module(modules::Fs)?;
        self.load_module(modules::Net)?;
        self.load_module(modules::I3wm)?;
        self.load_module(modules::Util)?;
        self.load_module(modules::Desktop)?;
        self.load_module(modules::Multimedia)?;
        self.load_module(modules::Extra)?;

        if let Some(dir) = get_config_dir(ConfigDir::RootDir) {
            if let Ok(mut f) = File::open(dir.join("init.lua")) {
                self.lua.load(f.read_everything()?).exec()?;
            }
        }

        Ok(())
    }

    pub fn load_module(&mut self, m: impl Module) -> Result<(), LuaError> {
        m.load(self)?;
        Ok(())
    }

    pub fn run_knife(&mut self, name: &str) -> Result<(), LuaError> {
        let found = std::sync::Mutex::new(false);
        self.knifes.par_iter().for_each(|knife| {
            if knife.name == name {
                if !PathBuf::from(&knife.init).exists() {
                    return;
                }
                let mut f = File::open(&knife.init).expect("Failed to open file for reading");
                let mut buf = String::new();
                f.read_to_string(&mut buf)
                    .expect("Failed to read to buffer");

                match self.lua.load(buf).exec() {
                    Ok(_) => {
                        *found.lock().unwrap() = true;
                    }
                    Err(e) => {
                        *found.lock().unwrap() = true;
                        urs::log!([error] "Failed to run knife: {e}");
                    }
                }
            }
        });

        if !*found.lock().unwrap() {
            log::log!([warn] "No knife found: {name}");
        }

        Ok(())
    }
}