pub struct Decoder { /* private fields */ }Expand description
Incremental decoder for a GridConnect byte stream (serial port, TCP socket,
or any other byte transport). Frames may be split arbitrarily across push calls and
may be separated by any whitespace (or nothing at all).
Bytes outside a :…; token are ignored, so the decoder recovers from
line noise and from joining a stream mid-frame. A : always starts a new
token; if a previous token was still open, it is reported as
Err(ParseError::Format("unterminated frame")). A token that grows past
32 characters without a ; is discarded (reported as
ParseError::Length). The decoder never allocates on its own: its
buffer is a fixed 32-byte array.
use rolcb::gridconnect::Decoder;
let mut d = Decoder::new();
// A read can end in the middle of a frame…
assert!(d.push(b"junk:X10700").is_empty());
// …and the next one may hold the rest plus more frames.
let frames = d.push(b"285N;\n:X19100285N050101012200;");
assert_eq!(frames.len(), 2);
assert_eq!(frames[0].as_ref().unwrap().id, 0x1070_0285);
assert_eq!(frames[1].as_ref().unwrap().data(), &[5, 1, 1, 1, 0x22, 0]);
// Malformed frames are reported, and decoding carries on.
let frames = d.push(b":X1G;:X10700285N;");
assert!(frames[0].is_err());
assert!(frames[1].is_ok());Implementations§
Source§impl Decoder
impl Decoder
Sourcepub fn push(&mut self, bytes: &[u8]) -> Vec<Result<CanFrame, ParseError>>
pub fn push(&mut self, bytes: &[u8]) -> Vec<Result<CanFrame, ParseError>>
Feed bytes; returns every complete frame found. Malformed frames are
returned as Err so callers can log them, and decoding continues.
To skip errors, flatten the result:
for frame in decoder.push(bytes).into_iter().flatten() { … }.
Sourcepub fn push_with<F>(&mut self, bytes: &[u8], f: F)
pub fn push_with<F>(&mut self, bytes: &[u8], f: F)
Feed bytes and call f for every complete (or malformed) frame, in
order, without allocating. Same rules as Decoder::push.
use rolcb::gridconnect::Decoder;
let mut d = Decoder::new();
let mut ids = Vec::new();
d.push_with(b":X10700285N;:X10701285N050101012200;", |r| {
if let Ok(frame) = r {
ids.push(frame.id);
}
});
assert_eq!(ids, [0x1070_0285, 0x1070_1285]);