feat: xserial-client with session management, mlua integration, and 238 tests

- Session: background I/O task with SessionHandle for send/read/close/reconfigure
- SessionManager: multi-session collection with aggregated event broadcast
- Config: serializable SessionConfig/PipelineConfig/FramerConfig/DecoderConfig
- Lua: xserial global (open/list_ports/sleep/log) + session userdata API
- RingBuffer: bounded history buffer with pipeline filtering
- Core: added Serialize/Deserialize+Default to Endian/TextEncoding/PlotFormat
- Core: added Send bound to Framer trait for tokio task compatibility
- 238 tests (193 core + 10 config + 7 Lua + 9 session + 18 pipeline + 1 doctest)
This commit is contained in:
2026-06-08 00:25:59 +08:00
parent 60c60a8044
commit 530986d068
19 changed files with 1494 additions and 16 deletions

View File

@@ -0,0 +1,38 @@
use std::sync::atomic::{AtomicU64, Ordering};
use mlua::{Lua, Result as LuaResult, Table, Value, LuaSerdeExt};
use crate::config::SessionConfig;
use crate::session::Session;
mod session_api;
static NEXT_ID: AtomicU64 = AtomicU64::new(1);
pub fn register(lua: &Lua) -> LuaResult<()> {
let xserial = lua.create_table()?;
xserial.set("open", lua.create_async_function(move |lua, config: Table| {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
async move {
let cfg: SessionConfig = lua.from_value(Value::Table(config))?;
let handle = Session::spawn(id, cfg);
lua.create_userdata(session_api::LuaSessionHandle::new(handle))
}
})?)?;
xserial.set("list_ports", lua.create_function(|_, ()| {
let ports = xserial_core::transport::serial::SerialTransport::list_ports();
Ok(ports.into_iter().map(|p| p.port_name).collect::<Vec<_>>())
})?)?;
xserial.set("sleep", lua.create_async_function(|_, ms: u64| async move {
tokio::time::sleep(std::time::Duration::from_millis(ms)).await;
Ok(())
})?)?;
xserial.set("log", lua.create_function(|_, msg: String| {
tracing::info!("[lua] {}", msg);
Ok(())
})?)?;
lua.globals().set("xserial", xserial)?;
Ok(())
}