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.