#[cfg(unix)]
use bnb::bin;
#[cfg(unix)]
#[bin(big, magic = b"RPC")]
#[derive(Debug, Clone, PartialEq, Eq)]
enum Message {
#[bin(magic = 0x01u8)]
Echo {
#[brw(count_prefix = u8)] #[try_str]
text: Vec<u8>,
},
#[bin(magic = 0x02u8)]
Bye,
}
#[cfg(unix)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use bnb::MessageStream;
use std::os::unix::net::{UnixListener, UnixStream};
use std::thread;
use tracing::info;
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.with_target(false)
.without_time()
.init();
let path = std::env::temp_dir().join(format!("bnb-unix-stream-{}.sock", std::process::id()));
let _ = std::fs::remove_file(&path);
let listener = UnixListener::bind(&path)?;
let server = thread::spawn(move || {
let (stream, _) = listener.accept().expect("accept");
let mut conn = MessageStream::new(stream); loop {
let req = match conn.read_message::<Message>() {
Ok(req) => req,
Err(bnb::BitError {
kind: bnb::ErrorKind::Io(std::io::ErrorKind::UnexpectedEof),
..
}) => break, Err(e) => panic!("unix server: framing/transport error: {e}"),
};
info!(?req, "unix server ← request");
match req {
Message::Echo { text } => {
conn.write_message(&Message::Echo { text }).expect("write")
}
Message::Bye => break,
}
}
});
let mut conn = MessageStream::new(UnixStream::connect(&path)?);
conn.write_message(&Message::Echo {
text: b"hello over a unix socket".to_vec(),
})?;
let reply = conn.read_message::<Message>()?;
info!(?reply, "unix client ← reply");
assert!(matches!(reply, Message::Echo { .. }));
conn.write_message(&Message::Bye)?;
server.join().expect("server thread");
let _ = std::fs::remove_file(&path);
info!("all checks passed");
Ok(())
}
#[cfg(not(unix))]
fn main() {
println!("unix_stream requires a Unix platform; skipping");
}