Struct flipdot_core::Frame[][src]

pub struct Frame<'a> { /* fields omitted */ }

A low-level representation of an Intel HEX data frame.

The Luminator protocol uses the Intel HEX format but not its semantics. This struct handles parsing the raw bytes into a form we can reason about, dealing with checksums, and so forth. It makes no attempt to ascribe meaning to the address, message type, and data (that’s Message’s job).

Both owned and borrowed data are supported.

Examples

use flipdot_core::{Address, Data, Frame, MsgType};

let frame = Frame::new(Address(2), MsgType(1), Data::try_new(vec![3, 31])?);
println!("Parsed frame is {}", frame);

let bytes = frame.to_bytes();
assert_eq!(b":02000201031FD9", bytes.as_slice());

let parsed = Frame::from_bytes(&bytes)?;
assert_eq!(parsed, frame);

Format Details

The format consists of a leading colon, several numeric fields (two-character ASCII representations of hex bytes), and a final carriage return/linefeed terminator. Note that for convenience, Frame allows omitting the final CRLF sequence.

┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬ ┄ ┬────┬────┬────┬────┬────┬────┐
│ :  │ DataLen │      Address      │ MsgType │  Data 0 │...│  Data N │  Chksum │ \r │ \n │
└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴ ┄ ┴────┴────┴────┴────┴────┴────┘
          └╌╌╌╌╌╌╌╌╌╌╌╌╌ # of ╌╌╌╌╌╌╌╌╌╌╌╌╌> ┆       Data bytes      ┆

The DataLen field describes how many two-character data byte sequences are present. Note that since it is represented as a single byte, the data length cannot exceed 255 (0xFF). If DataLen is 0, there are no data bytes, and MsgType is followed directly by Chksum. The checksum is a longitudinal redundancy check calculated on all numeric fields.

Implementations

impl<'a> Frame<'a>[src]

pub fn new(address: Address, message_type: MsgType, data: Data<'a>) -> Self[src]

Constructs a new Frame with the specified address, message type, and data.

Examples

// some_data is moved into owning_frame.
let some_data = vec![1, 2, 3];
let owning_frame = Frame::new(Address(0xB), MsgType(0xA), Data::try_new(some_data)?);

// other_data is borrowed.
let other_data = vec![1, 2, 3];
let borrowing_frame = Frame::new(Address(0xD), MsgType(0xC), Data::try_new(other_data.as_slice())?);

pub fn message_type(&self) -> MsgType[src]

Returns the message type of the frame.

Examples

let frame = Frame::new(Address(1), MsgType(1), Data::try_new(vec![])?);
match frame.message_type() {
   MsgType(1) => println!("Message 1"),
   _ => println!("Something else"),
}

pub fn address(&self) -> Address[src]

Returns the address of the frame.

Examples

let frame = Frame::new(Address(1), MsgType(1), Data::try_new(vec![])?);
if frame.address() == Address(3) {
    println!("This frame is addressed to me!");
}

pub fn data(&self) -> &Cow<'a, [u8]>[src]

Returns a reference to the frame’s data.

Examples

let frame = Frame::new(Address(1), MsgType(1), Data::try_new(vec![10, 20])?);
if (frame.data().as_ref() == &[10, 20]) {
    println!("Found the expected data!");
}

pub fn into_data(self) -> Data<'a>[src]

Consumes the frame and returns ownership of its data.

Examples

let frame = Frame::new(Address(1), MsgType(1), Data::try_new(vec![6, 7])?);
let frame2 = Frame::new(Address(2), MsgType(2), frame.into_data());

pub fn to_bytes(&self) -> Vec<u8>[src]

Converts the frame to its wire format, without trailing carriage return/linefeed.

Examples

let frame = Frame::new(Address(2), MsgType(1), Data::try_new(vec![3, 31])?);
let bytes = frame.to_bytes();
assert_eq!(b":02000201031FD9", bytes.as_slice());

pub fn to_bytes_with_newline(&self) -> Vec<u8>[src]

Converts the frame to its wire format, including trailing carriage return/linefeed.

Examples

let frame = Frame::new(Address(2), MsgType(1), Data::try_new(vec![3, 31])?);
let bytes = frame.to_bytes_with_newline();
assert_eq!(b":02000201031FD9\r\n", bytes.as_slice());

pub fn from_bytes(bytes: &[u8]) -> Result<Self, FrameError>[src]

Parses the Intel HEX wire format into a new Frame.

Errors

Returns:

Examples

let bytes = b":02000201031FD9\r\n";
let frame = Frame::from_bytes(&bytes[..])?;
assert_eq!(Frame::new(Address(2), MsgType(1), Data::try_new(vec![3, 31])?), frame);

pub fn write<W: Write>(&self, writer: &mut W) -> Result<(), FrameError>[src]

Writes the byte representation (including CRLF) of the frame to a writer.

Errors

Returns FrameError::Io if the write fails.

Examples

let mut port = serial::open("COM3")?;
let frame = Frame::new(Address(2), MsgType(1), Data::try_new(vec![3, 31])?);
frame.write(&mut port)?;

pub fn read<R: Read>(reader: &mut R) -> Result<Self, FrameError>[src]

Reads the next line (up to \n) from the reader and converts the result into a new Frame.

Errors

Returns:

Examples

let mut port = serial::open("COM3")?;
let frame = Frame::read(&mut port)?;

Trait Implementations

impl<'a> Clone for Frame<'a>[src]

impl<'a> Debug for Frame<'a>[src]

impl Display for Frame<'_>[src]

fn fmt(&self, f: &mut Formatter<'_>) -> Result[src]

Formats the frame in a human-readable way.

Useful for viewing traffic on a bus. All numbers are in hex.

impl<'a> Eq for Frame<'a>[src]

impl<'a> From<Frame<'a>> for Message<'a>[src]

fn from(frame: Frame<'a>) -> Self[src]

Converts a Frame into a Message.

This cannot fail as all valid Frames are representable as Messages (though perhaps Unknown). The input Frame is consumed to allow efficiently reusing its data where possible.

Examples

let frame = Frame::new(Address(0x12), MsgType(4), Data::try_new(vec![0x07])?);
let message = Message::from(frame);
assert_eq!(Message::ReportState(Address(0x12), State::ConfigReceived), message);

impl<'a> From<Message<'a>> for Frame<'a>[src]

fn from(message: Message<'a>) -> Self[src]

Converts a Message into a Frame.

This cannot fail as all Messages can be represented as Frames. The input Message is consumed to allow efficiently reusing its data where possible.

Examples

let message = Message::ReportState(Address(0xFF), State::ConfigReceived);
let frame = Frame::from(message);
assert_eq!(Frame::new(Address(0xFF), MsgType(4), Data::try_new(vec![0x07])?), frame);

impl<'a> Hash for Frame<'a>[src]

impl<'a> PartialEq<Frame<'a>> for Frame<'a>[src]

impl<'a> StructuralEq for Frame<'a>[src]

impl<'a> StructuralPartialEq for Frame<'a>[src]

Auto Trait Implementations

impl<'a> RefUnwindSafe for Frame<'a>

impl<'a> Send for Frame<'a>

impl<'a> Sync for Frame<'a>

impl<'a> Unpin for Frame<'a>

impl<'a> UnwindSafe for Frame<'a>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.