use crate::serial::Serial;
use mlua::Error::RuntimeError;
use mlua::{Error, FromLua, Lua, MultiValue};
use std::str::from_utf8;
use std::time::Duration;
pub(super) fn handle(lua: &Lua, serial: &Serial, arg: MultiValue) -> Result<String, Error> {
let args: Vec<_> = arg.into_iter().collect();
let (length, timeout_ms) = {
if args.is_empty() {
return Err(RuntimeError("A length <number> arg is required".to_string()));
}
let length: usize = usize::from_lua(args[0].clone(), lua)?;
let timeout_ms = {
if args.len() >= 2 {
u64::from_lua(args[1].clone(), lua)?
} else {
15_000_u64
}
};
(length, timeout_ms)
};
let (bytes_read, buf) = {
let mut locked_port = serial.port.lock().map_err(|err| RuntimeError(err.to_string()))?;
locked_port.set_read_timeout(Duration::from_millis(timeout_ms))?;
let arr = vec![0_u8; length];
let mut buf = arr.into_boxed_slice();
let bytes_read = match locked_port.read(&mut buf) {
Ok(bytes_read) => Ok(bytes_read),
Err(e) if e.kind() == std::io::ErrorKind::TimedOut => Ok(0),
Err(e) => Err(e),
}?;
(bytes_read, buf)
};
let res: &[u8] = &buf[0..bytes_read];
let str = from_utf8(res)?;
Ok(str.to_string())
}