use super::Gpio;
use super::configure::{configure_event_request_flags, configure_line_request_flags};
use gpio_cdev::{Chip, LineEventHandle};
use mlua::{Error, FromLua, Lua, Table, Value};
use std::sync::{Arc, Mutex};
pub(super) fn handle(lua: &Lua, args: mlua::MultiValue) -> Result<Gpio, Error> {
let mut bias = String::default();
let mut drive = String::default();
let mut edge = String::default();
let mut inverted = false;
let mut label = String::default();
let args: Vec<Value> = args.into_iter().collect();
let (path, line_num, direction): (String, u32, String) = match args.len() {
2 => {
let table: Table = Table::from_lua(args[1].clone(), lua)?;
let path: String = table.get("path")?;
let line = table.get("line")?;
let direction: String = table.get("direction")?;
if table.contains_key("bias")? {
bias = table.get("bias")?;
}
if table.contains_key("drive")? {
drive = table.get("drive")?;
}
if table.contains_key("edge")? {
edge = table.get("edge")?;
}
if table.contains_key("inverted")? {
inverted = table.get("inverted")?;
}
if table.contains_key("label")? {
label = table.get("label")?;
}
Ok((path, line, direction))
}
4 => {
let path = String::from_lua(args[1].clone(), lua)?;
let line = u32::from_lua(args[2].clone(), lua)?;
let direction = String::from_lua(args[3].clone(), lua)?;
Ok((path, line, direction))
}
_ => Err(Error::RuntimeError("Unsupported args".to_string())),
}?;
let chip = Arc::new(Mutex::new(
Chip::new(path).map_err(|err| Error::RuntimeError(err.to_string()))?,
));
let line = chip
.lock()
.map_err(|err| Error::RuntimeError(err.to_string()))?
.get_line(line_num)
.map_err(|err| Error::RuntimeError(err.to_string()))?;
let line_events: Option<LineEventHandle> = {
match configure_line_request_flags(&direction) {
Err(_e) => None,
Ok(line_request_flags) => match configure_event_request_flags(&edge) {
Err(_e) => None,
Ok(event_request_flags) => Some(
line.events(line_request_flags, event_request_flags, "periphery:read_event()")
.map_err(|err| Error::RuntimeError(err.to_string()))?,
),
},
}
};
Ok(Gpio {
bias: Arc::new(Mutex::new(bias)),
chip,
direction: Arc::new(Mutex::new(direction)),
drive: Arc::new(Mutex::new(drive)),
edge: Arc::new(Mutex::new(edge)),
inverted: Arc::new(Mutex::new(inverted)),
label: Arc::new(Mutex::new(label)),
line: Arc::new(Mutex::new(line)),
line_events: Arc::new(Mutex::new(line_events)),
line_num,
})
}