autosway 0.3.0

Automation program
Documentation
use super::*;
use swayipc::{Connection, EventType};

struct LuaI3Event(EventType);
impl LuaUserData for LuaI3Event {}

pub struct I3;

impl Module for I3 {
    fn load(&self, state: &mut State) -> Result<(), LuaError> {
        let module = state.lua.create_table()?;

        module.set("EVENT_WORKSPACE", LuaI3Event(EventType::Workspace))?;
        module.set("EVENT_OUTPUT", LuaI3Event(EventType::Output))?;
        module.set("EVENT_MODE", LuaI3Event(EventType::Mode))?;
        module.set("EVENT_WINDOW", LuaI3Event(EventType::Window))?;
        module.set(
            "EVENT_BARCONFIG_UPDATE",
            LuaI3Event(EventType::BarConfigUpdate),
        )?;
        module.set("EVENT_BINDING", LuaI3Event(EventType::Binding))?;
        module.set("EVENT_SHUTDOWN", LuaI3Event(EventType::Shutdown))?;
        module.set("EVENT_TICK", LuaI3Event(EventType::Tick))?;
        module.set(
            "EVENT_BARSTATE_UPDATE",
            LuaI3Event(EventType::BarStateUpdate),
        )?;
        module.set("EVENT_INPUT", LuaI3Event(EventType::Input))?;

        module.set(
            "run_command",
            state.lua.create_function(|_, command: String| {
                match Connection::new() {
                    Ok(mut c) => match c.run_command(command) {
                        Ok(_) => {}
                        Err(_) => return Ok(LuaValue::Boolean(false)),
                    },
                    Err(_) => return Ok(LuaValue::Boolean(false)),
                }

                Ok(LuaValue::Boolean(true))
            })?,
        )?;

        module.set(
            "get_workspaces",
            state.lua.create_function(|lua, _: ()| {
                let mut jsons: Vec<String> = vec![];
                if let Ok(mut c) = Connection::new() {
                    if let Ok(ws) = c.get_workspaces() {
                        for w in ws {
                            if let Ok(s) = serde_json::to_string(&w) {
                                jsons.push(s)
                            };
                        }
                    }
                };
                Ok(jsons.into_lua(lua))
            })?,
        )?;

        module.set(
            "get_outputs",
            state.lua.create_function(|lua, _: ()| {
                let mut jsons: Vec<String> = vec![];
                if let Ok(mut c) = Connection::new() {
                    if let Ok(ws) = c.get_outputs() {
                        for w in ws {
                            if let Ok(s) = serde_json::to_string(&w) {
                                jsons.push(s)
                            };
                        }
                    }
                };
                Ok(jsons.into_lua(lua))
            })?,
        )?;

        module.set(
            "get_tree",
            state.lua.create_function(|lua, _: ()| {
                if let Ok(mut c) = Connection::new() {
                    if let Ok(ws) = c.get_tree() {
                        if let Ok(s) = serde_json::to_string(&ws) {
                            return s.into_lua(lua);
                        };
                    }
                };
                Ok(LuaValue::Nil)
            })?,
        )?;

        module.set(
            "get_seats",
            state.lua.create_function(|lua, _: ()| {
                if let Ok(mut c) = Connection::new() {
                    if let Ok(ws) = c.get_seats() {
                        if let Ok(s) = serde_json::to_string(&ws) {
                            return s.into_lua(lua);
                        }
                    }
                };

                Ok(LuaValue::Nil)
            })?,
        )?;

        module.set(
            "get_inputs",
            state.lua.create_function(|lua, _: ()| {
                if let Ok(mut c) = Connection::new() {
                    if let Ok(ws) = c.get_inputs() {
                        if let Ok(s) = serde_json::to_string(&ws) {
                            return s.into_lua(lua);
                        }
                    }
                };

                Ok(LuaValue::Nil)
            })?
        )?;

        module.set(
            "subscribe_event",
            state.lua.create_function(
                |_, (event_type, callback): (LuaAnyUserData, LuaFunction)| {
                    let event_type = if event_type.is::<LuaI3Event>() {
                        event_type.take::<LuaI3Event>()?
                    } else {
                        return Ok(LuaValue::Boolean(false));
                    };

                    let c = match Connection::new() {
                        Ok(c) => c,
                        Err(_) => return Ok(LuaValue::Boolean(false)),
                    };

                    let stream = match c.subscribe(vec![event_type.0]) {
                        Ok(s) => s,
                        Err(_) => return Ok(LuaValue::Boolean(false)),
                    };

                    for r_event in stream {
                        let event = match r_event {
                            Ok(e) => e,
                            Err(_) => continue,
                        };

                        match event.event_type() {
                            e if e == event_type.0 => {
                                match serde_json::to_string(&event) {
                                    Ok(s) => callback.call::<LuaValue>(s)?,
                                    Err(_) => callback.call::<LuaValue>(LuaValue::Nil)?,
                                };
                            }
                            _ => {}
                        }
                    }

                    Ok(LuaValue::Nil)
                },
            )?,
        )?;

        create_module(&state.lua, "autosway.i3", module)?;

        Ok(())
    }
}