mlua-periphery 1.2.4

A Rust-native implementation of lua-periphery for mlua.
use super::Config;
use super::Serial;
use mlua::Error::RuntimeError;
use mlua::{FromLua, Lua, Table, Value};
use serial2::{CharSize, FlowControl, Parity, SerialPort, StopBits};
use std::sync::{Arc, Mutex};

pub(super) fn handle(lua: &Lua, args: mlua::MultiValue) -> Result<Serial, mlua::Error> {
    // Establish defaults
    let mut baudrate = 0_u32;
    let mut char_size = CharSize::Bits8;
    let mut flow_control = FlowControl::None;
    let mut parity = Parity::None;
    let mut stopbits = StopBits::One;

    let args: Vec<Value> = args.into_iter().collect();
    let device: String = match args.len() {
        2 => {
            let table: Table = Table::from_lua(args[1].clone(), lua)?;

            // Required keys
            baudrate = table.get("baudrate")?;
            let device: String = table.get("device")?;

            // Optional keys
            if table.contains_key("databits")? {
                let databits: u8 = table.get("databits")?;
                char_size = match databits {
                    5 => CharSize::Bits5,
                    6 => CharSize::Bits6,
                    7 => CharSize::Bits7,
                    8 => CharSize::Bits8,
                    _ => Err(RuntimeError(
                        "Supported databits; allowed values: [5,6,7,8]".to_string(),
                    ))?,
                }
            }
            if table.contains_key("parity")? {
                let parity_: String = table.get("parity")?;
                parity = match parity_.as_str() {
                    "even" => Parity::Even,
                    "none" => Parity::None,
                    "odd" => Parity::Odd,
                    _ => Err(RuntimeError("Unsupported parity".to_string()))?,
                }
            }
            if table.contains_key("rtscts")? && table.get::<bool>("rtscts")? {
                flow_control = FlowControl::RtsCts;
            } else if table.contains_key("xonxoff")? && table.get::<bool>("xonxoff")? {
                flow_control = FlowControl::XonXoff;
            }
            if table.contains_key("stopbits")? {
                let stopbits_: u8 = table.get("stopbits")?;
                stopbits = match stopbits_ {
                    1 => StopBits::One,
                    2 => StopBits::Two,
                    _ => Err(RuntimeError("Supported stopbits; allowed values: [1,2]".to_string()))?,
                }
            }

            Ok(device)
        }
        3 => {
            let device = String::from_lua(args[1].clone(), lua)?;
            baudrate = u32::from_lua(args[2].clone(), lua)?;
            Ok(device)
        }
        _ => Err(RuntimeError("Unsupported args".to_string())),
    }?;

    let config = Config {
        baudrate,
        char_size,
        flow_control,
        parity,
        stopbits,
    };
    let port = Arc::new(Mutex::new(SerialPort::open(&device, config)?));
    Ok(Serial { device, port })
}