pub mod binder; use std::{ fs, io::{self, Read, Write}, os::unix::net::UnixListener, }; pub trait Lib { fn init(&mut self); fn call(&mut self, id: u8); } pub fn run(mut dyn_lib: L, dyn_lib_id: &str) -> io::Result<()> { let path = &format!("/tmp/{dyn_lib_id}"); let _ = fs::remove_file(path); let listener = UnixListener::bind(path)?; println!("Listening on {path}"); dyn_lib.init(); for stream in listener.incoming() { match stream { Ok(mut sock) => loop { match read_line(&mut sock) { Some(id) => { println!("Calling {id:?}"); dyn_lib.call(id[0]); sock.write_all(&[0x52, 255])?; sock.flush()?; } None => { break; } } }, Err(e) => { eprintln!("Connection failed: {e}"); } } } Ok(()) } pub fn read_line(stream: &mut T) -> Option> { let mut buffer = Vec::new(); loop { let mut tmp = [0u8; 1]; stream.read_exact(&mut tmp).ok()?; buffer.extend_from_slice(&tmp); if tmp[0] == 255 { break; } } Some(buffer) } #[macro_export] macro_rules! lib { ($(fn $id:literal() $(-> $t:ty)? $body:block)*) => { fn call(&mut self, id: u8) { match id { $($id => $body)* _ => {} } } }; }