use futures_util::SinkExt;
use futures_util::stream::StreamExt;
use lightstream::models::encoders::tlv::TLVEncoder;
use lightstream::models::encoders::tlv::tlv_stream::TLVStreamWriter;
use lightstream::models::frames::tlv_frame::TLVFrame;
use lightstream::models::sinks::tlv_sink::TLVSink;
use lightstream::traits::frame_encoder::FrameEncoder;
use minarrow::Vec64;
use tokio::io::{AsyncReadExt, duplex};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("1. Basic TLV Encoding");
let frames = [
TLVFrame {
t: 1,
value: b"Hello",
},
TLVFrame {
t: 2,
value: b"World",
},
TLVFrame {
t: 42,
value: &[0xDE, 0xAD, 0xBE, 0xEF],
},
TLVFrame { t: 100, value: b"" },
];
for frame in &frames {
let mut offset = 0;
let (encoded, _) = TLVEncoder::encode::<Vec64<u8>>(&mut offset, frame)?;
assert_eq!(encoded[0], frame.t);
assert_eq!(encoded.len(), 1 + 4 + frame.value.len());
println!(
" Type={}, Len={}, Encoded={} bytes",
frame.t,
frame.value.len(),
encoded.len()
);
}
println!("\n2. TLV Streaming");
let mut writer = TLVStreamWriter::<Vec64<u8>>::new();
writer.write_frame(10, b"Stream")?;
writer.write_frame(20, b"Data")?;
writer.write_frame(30, &[1, 2, 3, 4, 5])?;
writer.finish();
let mut count = 0;
while let Some(result) = writer.next().await {
let frame = result?;
count += 1;
let frame_type = frame[0];
let length = u32::from_le_bytes(frame[1..5].try_into().unwrap());
println!(" Frame {}: Type={}, Length={}", count, frame_type, length);
}
println!("\n3. Async TLV Sink");
let (client, mut server) = duplex(256);
let mut sink = TLVSink::<_, Vec64<u8>>::new(client);
let payloads: &[(&[u8], u8)] = &[(b"Async", 200), (b"TLV", 201), (b"Sink", 202)];
for &(value, t) in payloads {
sink.send(TLVFrame { t, value }).await?;
}
sink.close().await?;
for &(expected_value, expected_type) in payloads {
let mut buf = vec![0u8; 1 + 4 + expected_value.len()];
server.read_exact(&mut buf).await?;
assert_eq!(buf[0], expected_type);
assert_eq!(&buf[5..], expected_value);
println!(
" Received: Type={}, Value={:?}",
buf[0],
String::from_utf8_lossy(&buf[5..])
);
}
let n = server.read(&mut [0u8; 1]).await?;
assert_eq!(n, 0, "Stream should be closed");
println!("\nAll TLV examples completed.");
Ok(())
}