pub struct SmlReader<R, Buf>where
R: ByteSource,
Buf: Buffer,{ /* private fields */ }Expand description
Main API of sml-rs
SmlReader is used to read sml data. It allows reading from various data
sources and can produce different output depending on the use-case.
§Example
The following example shows how to parse an sml data set from a file:
use std::fs;
let f = fs::File::open("sample.bin").unwrap();
let mut reader = SmlReader::from_reader(f);
match reader.read::<File>() {
Ok(x) => println!("Got result: {:#?}", x),
Err(e) => println!("Error: {:?}", e),
}§Data Source
The SmlReader struct can be used with several kinds of data providers:
Constructor (SmlReader::...) | Expected data type | Usage examples |
|---|---|---|
from_reader ¹ | impl std::io::Read | files, sockets, serial ports (see serialport-rs crate) |
from_eh_reader ² | impl embedded_hal::serial::Read<u8> | microcontroller pins |
from_slice | &[u8] | arrays, vectors, … |
from_iterator | impl IntoIterator<Item = impl Borrow<u8>>) | anything that can be turned into an iterator over bytes |
¹ requires feature std (on by default); ² requires optional feature embedded_hal
§Internal Buffer
SmlReader reads sml messages into an internal buffer. By default, a static
buffer with a size of 8 KiB is used, which should be more than enough for
typical messages.
It is possible to use a different static buffer size or use a dynamically
allocated buffer that can grow as necessary. SmlReader provides two associated
functions for this purpose:
SmlReader::with_static_buffer<N>()SmlReader::with_vec_buffer()(requires featurealloc(on by default))
These functions return a builder object (SmlReaderBuilder) that provides methods to create an SmlReader
from the different data sources shown above.
Examples
Creating a reader with a static 1KiB buffer from a slice:
let data = [1, 2, 3, 4, 5];
let reader = SmlReader::with_static_buffer::<1024>().from_slice(&data);Creating a reader with a dynamically-sized buffer from an iterable:
let data = [1, 2, 3, 4, 5];
let reader_2 = SmlReader::with_vec_buffer().from_iterator(&data);§Reading transmissions
Once a SmlReader is instantiated, it can be used to read, decode and parse SML messages. SmlReader
provides two functions for this, read<T> and next<T>.
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = reader.read::<DecodedBytes>();
assert!(matches!(bytes, Ok(bytes)));
let bytes = reader.read::<DecodedBytes>();
assert!(matches!(bytes, Err(_)));
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = reader.next::<DecodedBytes>();
assert!(matches!(bytes, Some(Ok(bytes))));
let bytes = reader.next::<DecodedBytes>();
assert!(matches!(bytes, None));§Target Type
read<T> and next<T> can be used to parse sml
transmissions into several different representations:
DecodedBytes: a slice of bytes containing the decoded message. No parsing is done.File: a struct containing completely parsed sml data. (requires feature"alloc")Parser: an streaming parser for sml data.
Examples
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = reader.read::<DecodedBytes>();
let file = reader.read::<File>();
let parser = reader.read::<Parser>();Implementations§
Source§impl SmlReader<SliceReader<'static>, ArrayBuf<0>>
impl SmlReader<SliceReader<'static>, ArrayBuf<0>>
Sourcepub fn with_static_buffer<const N: usize>() -> SmlReaderBuilder<ArrayBuf<N>>
pub fn with_static_buffer<const N: usize>() -> SmlReaderBuilder<ArrayBuf<N>>
Returns a builder with a static internal buffer of size N.
Use the from_* methods on the builder to create an SmlReader.
§Examples
let data = [1, 2, 3];
let reader = SmlReader::with_static_buffer::<1024>().from_slice(&data);Sourcepub fn with_vec_buffer() -> SmlReaderBuilder<Vec<u8>>
Available on crate feature alloc only.
pub fn with_vec_buffer() -> SmlReaderBuilder<Vec<u8>>
alloc only.Returns a builder with a dynamically-sized internal buffer.
Use the from_* methods on the builder to create an SmlReader.
This function is available only if sml-rs is built with the "alloc" feature.
§Examples
let data = [1, 2, 3];
let reader = SmlReader::with_vec_buffer().from_slice(&data);Sourcepub fn from_reader<R>(reader: R) -> SmlReader<IoReader<R>, ArrayBuf<{ _ }>>where
R: Read,
Available on crate feature std only.
pub fn from_reader<R>(reader: R) -> SmlReader<IoReader<R>, ArrayBuf<{ _ }>>where
R: Read,
std only.Build an SmlReader from a type implementing std::io::Read.
This function is available only if sml-rs is built with the "std" feature.
§Examples
let data = [1, 2, 3];
let cursor = std::io::Cursor::new(data); // implements std::io::Read
let reader = SmlReader::from_reader(cursor);Sourcepub fn from_eh_reader<R, E>(
reader: R,
) -> SmlReader<EhReader<R, E>, ArrayBuf<{ _ }>>
Available on crate feature embedded_hal only.
pub fn from_eh_reader<R, E>( reader: R, ) -> SmlReader<EhReader<R, E>, ArrayBuf<{ _ }>>
embedded_hal only.Build an SmlReader from a type implementing embedded_hal::serial::Read<u8>.
This function is available only if sml-rs is built with the "embedded-hal" feature.
§Examples
// usually provided by hardware abstraction layers (HALs) for specific chips
// let pin = ...;
let reader = SmlReader::from_eh_reader(pin);Sourcepub fn from_slice(reader: &[u8]) -> SmlReader<SliceReader<'_>, ArrayBuf<{ _ }>>
pub fn from_slice(reader: &[u8]) -> SmlReader<SliceReader<'_>, ArrayBuf<{ _ }>>
Build an SmlReader from a slice of bytes.
§Examples
let data: &[u8] = &[1, 2, 3];
let reader = SmlReader::from_slice(data);Sourcepub fn from_iterator<B, I>(
iter: I,
) -> SmlReader<IterReader<I::IntoIter, B>, ArrayBuf<{ _ }>>
pub fn from_iterator<B, I>( iter: I, ) -> SmlReader<IterReader<I::IntoIter, B>, ArrayBuf<{ _ }>>
Build an SmlReader from a type that can be turned into a byte iterator.
§Examples
let data: [u8; 3] = [1, 2, 3];
let reader = SmlReader::from_iterator(data.clone()); // [u8; 3]
let reader = SmlReader::from_iterator(&data); // &[u8; 3]
let reader = SmlReader::from_iterator(data.as_slice()); // &[u8]
let reader = SmlReader::from_iterator(data.iter()); // impl Iterator<Item = &u8>
let reader = SmlReader::from_iterator(data.into_iter()); // impl Iterator<Item = u8>Source§impl<R, ReadErr, Buf> SmlReader<R, Buf>
impl<R, ReadErr, Buf> SmlReader<R, Buf>
Sourcepub fn read<'i, T>(&'i mut self) -> Result<T, T::Error>
pub fn read<'i, T>(&'i mut self) -> Result<T, T::Error>
Reads, decodes and possibly parses sml data.
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = reader.read::<DecodedBytes>();
assert!(matches!(bytes, Ok(bytes)));
let bytes = reader.read::<DecodedBytes>();
assert!(matches!(bytes, Err(_)));This method can be used to parse sml data into several representations. See the module documentation for more information.
When reading from a finite data source (such as a file containing a certain
number of transmissions), it’s easier to use next instead,
which returns None when an EOF is read when trying to read the next transmission.
See also read_nb, which provides a convenient API for
non-blocking byte sources.
Sourcepub fn next<'i, T>(&'i mut self) -> Option<Result<T, T::Error>>
pub fn next<'i, T>(&'i mut self) -> Option<Result<T, T::Error>>
Tries to read, decode and possibly parse sml data.
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = reader.next::<DecodedBytes>();
assert!(matches!(bytes, Some(Ok(bytes))));
let bytes = reader.next::<DecodedBytes>();
assert!(matches!(bytes, None));This method can be used to parse sml data into several representations. See the module documentation for more information.
When reading from a data source that will provide data infinitely (such
as from a serial port), it’s easier to use read instead.
See also next_nb, which provides a convenient API for
non-blocking byte sources.
Sourcepub fn read_nb<'i, T>(&'i mut self) -> Result<T, T::Error>
Available on crate feature nb only.
pub fn read_nb<'i, T>(&'i mut self) -> Result<T, T::Error>
nb only.Reads, decodes and possibly parses sml data (non-blocking).
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = nb::block!(reader.read_nb::<DecodedBytes>());
assert!(matches!(bytes, Ok(bytes)));
let bytes = nb::block!(reader.read_nb::<DecodedBytes>());
assert!(matches!(bytes, Err(_)));Same as read except that it returns nb::Result.
If reading from the byte source indicates that data isn’t available yet,
this method returns Err(nb::Error::WouldBlock).
Using nb::Result allows this method to be awaited using the nb::block! macro.
This function is available only if sml-rs is built with the "nb" or "embedded_hal" features.
Sourcepub fn next_nb<'i, T>(&'i mut self) -> Result<Option<T>, T::Error>
Available on crate feature nb only.
pub fn next_nb<'i, T>(&'i mut self) -> Result<Option<T>, T::Error>
nb only.Tries to read, decode and possibly parse sml data (non-blocking).
let data = include_bytes!("../sample.bin");
let mut reader = SmlReader::from_slice(data.as_slice());
let bytes = nb::block!(reader.next_nb::<DecodedBytes>());
assert!(matches!(bytes, Ok(Some(bytes))));
let bytes = nb::block!(reader.next_nb::<DecodedBytes>());
assert!(matches!(bytes, Ok(None)));Same as next except that it returns nb::Result.
If reading from the byte source indicates that data isn’t available yet,
this method returns Err(nb::Error::WouldBlock).
Using nb::Result allows this method to be awaited using the nb::block! macro.
This function is available only if sml-rs is built with the "nb" or "embedded_hal" features.