pub struct DynamicMessage<'a> { /* private fields */ }Expand description
A message read and written by field name against a MessageDescriptor.
This is the counterpart to a typed message: the same bytes, reached by name at runtime rather than through a struct known at compile time. It carries a full-size payload buffer and no allocation, so it works on a microcontroller as well as a ground station.
§Examples
use pamoja_mavlink::dialect::{descriptor, DynamicMessage, Heartbeat, Message};
use pamoja_mavlink::Header;
let shape = descriptor(Heartbeat::ID).expect("HEARTBEAT is in the common dialect");
// Fill the message in by name, the way a caller reading a dialect definition would.
let mut heartbeat = DynamicMessage::new(shape)?;
heartbeat.set_uint("type", 0, 18)?; // MAV_TYPE_ONBOARD_CONTROLLER
heartbeat.set_uint("system_status", 0, 4)?; // MAV_STATE_ACTIVE
heartbeat.set_uint("mavlink_version", 0, 3)?;
// It is an ordinary frame, so a typed receiver reads it back unchanged.
let frame = heartbeat.to_frame(Header::new(1, 1, 0))?;
assert_eq!(Heartbeat::decode(frame.payload())?.system_status, 4);Implementations§
Source§impl<'a> DynamicMessage<'a>
impl<'a> DynamicMessage<'a>
Sourcepub fn new(descriptor: &'a MessageDescriptor<'a>) -> Result<Self>
pub fn new(descriptor: &'a MessageDescriptor<'a>) -> Result<Self>
Creates a message with every field zero.
§Arguments
descriptor- the shape of the message to build.
§Returns
The zeroed message, ready for its fields to be set.
§Errors
Returns MavlinkError::PayloadTooLong if the descriptor’s fields exceed
MAX_PAYLOAD bytes, which no message from a valid dialect does.
Sourcepub fn decode(
descriptor: &'a MessageDescriptor<'a>,
payload: &[u8],
) -> Result<Self>
pub fn decode( descriptor: &'a MessageDescriptor<'a>, payload: &[u8], ) -> Result<Self>
Reads a message out of a frame payload.
A short payload is zero-extended, as MAVLink 2 truncation requires, so a frame from a peer that omitted trailing zeros or predates an extension field still decodes.
§Arguments
descriptor- the shape to read the payload as.payload- the frame payload.
§Returns
The decoded message.
§Errors
Returns MavlinkError::BadPayload if the payload is longer than the descriptor
describes, and MavlinkError::PayloadTooLong if the descriptor itself does not
fit a frame.
§Examples
use pamoja_mavlink::dialect::{descriptor, DynamicMessage};
use pamoja_mavlink::Frame;
let shape = descriptor(0).expect("HEARTBEAT is in the common dialect");
let received = Frame::parse(
&[0xfd, 0x09, 0, 0, 7, 1, 1, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 4, 3, 0x75, 0x3a],
shape.crc_extra,
)?;
let heartbeat = DynamicMessage::decode(shape, received.payload())?;
assert_eq!(heartbeat.get_uint("type", 0)?, 18);Sourcepub fn descriptor(&self) -> &'a MessageDescriptor<'a>
pub fn descriptor(&self) -> &'a MessageDescriptor<'a>
Sourcepub fn payload(&self) -> &[u8] ⓘ
pub fn payload(&self) -> &[u8] ⓘ
Returns the message’s bytes as they go on the wire.
§Returns
The payload, including any trailing zeros; a frame truncates those itself.
Sourcepub fn to_frame(&self, header: Header) -> Result<Frame>
pub fn to_frame(&self, header: Header) -> Result<Frame>
Builds a v2 frame carrying this message.
§Arguments
header- the addressing fields to stamp on the frame.
§Returns
The frame ready to send.
§Errors
Returns MavlinkError::PayloadTooLong if the message does not fit a frame.
Sourcepub fn get_int(&self, name: &str, index: usize) -> Result<i64>
pub fn get_int(&self, name: &str, index: usize) -> Result<i64>
Reads a field as a signed integer.
Any integer field can be read this way, whatever its width or sign.
§Arguments
name- the field name.index- the element to read, or0for a scalar field.
§Returns
The value.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
MavlinkError::FieldTypeMismatch for a floating-point field, and
MavlinkError::ValueOutOfRange for a uint64_t value above i64::MAX.
Sourcepub fn get_uint(&self, name: &str, index: usize) -> Result<u64>
pub fn get_uint(&self, name: &str, index: usize) -> Result<u64>
Reads a field as an unsigned integer.
Any integer field can be read this way, whatever its width or sign.
§Arguments
name- the field name.index- the element to read, or0for a scalar field.
§Returns
The value.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
MavlinkError::FieldTypeMismatch for a floating-point field, and
MavlinkError::ValueOutOfRange for a negative value.
Sourcepub fn get_float(&self, name: &str, index: usize) -> Result<f64>
pub fn get_float(&self, name: &str, index: usize) -> Result<f64>
Reads a floating-point field.
§Arguments
name- the field name.index- the element to read, or0for a scalar field.
§Returns
The value, widened to double precision for a float field.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
and MavlinkError::FieldTypeMismatch for an integer field.
Sourcepub fn get(&self, name: &str, index: usize) -> Result<FieldValue>
pub fn get(&self, name: &str, index: usize) -> Result<FieldValue>
Reads a field as whichever kind of value its type calls for.
§Arguments
name- the field name.index- the element to read, or0for a scalar field.
§Returns
The value.
§Errors
Returns MavlinkError::UnknownField if the message has no such field, and
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array.
Sourcepub fn set_int(&mut self, name: &str, index: usize, value: i64) -> Result<()>
pub fn set_int(&mut self, name: &str, index: usize, value: i64) -> Result<()>
Writes a signed integer into a field.
§Arguments
name- the field name.index- the element to write, or0for a scalar field.value- the value to store.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
MavlinkError::FieldTypeMismatch for a floating-point field, and
MavlinkError::ValueOutOfRange if the value does not fit the field’s type.
Sourcepub fn set_uint(&mut self, name: &str, index: usize, value: u64) -> Result<()>
pub fn set_uint(&mut self, name: &str, index: usize, value: u64) -> Result<()>
Writes an unsigned integer into a field.
§Arguments
name- the field name.index- the element to write, or0for a scalar field.value- the value to store.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
MavlinkError::FieldTypeMismatch for a floating-point field, and
MavlinkError::ValueOutOfRange if the value does not fit the field’s type.
Sourcepub fn set_float(&mut self, name: &str, index: usize, value: f64) -> Result<()>
pub fn set_float(&mut self, name: &str, index: usize, value: f64) -> Result<()>
Writes a floating-point field.
§Arguments
name- the field name.index- the element to write, or0for a scalar field.value- the value to store, narrowed to single precision for afloatfield.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
and MavlinkError::FieldTypeMismatch for an integer field.
Sourcepub fn get_number(&self, name: &str, index: usize) -> Result<f64>
pub fn get_number(&self, name: &str, index: usize) -> Result<f64>
Reads a field as a double, whatever its type.
This is the reading a host language with one numeric type needs. An integer field
wider than 53 bits can exceed what a double represents exactly, so read those with
get_int or get_uint where the exact value
matters.
§Arguments
name- the field name.index- the element to read, or0for a scalar field.
§Returns
The value as a double.
§Errors
Returns MavlinkError::UnknownField if the message has no such field, and
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array.
Sourcepub fn set_number(&mut self, name: &str, index: usize, value: f64) -> Result<()>
pub fn set_number(&mut self, name: &str, index: usize, value: f64) -> Result<()>
Writes a double into a field, converting it to the field’s type.
This is the writing a host language with one numeric type needs. A value bound for an integer field must be a whole number within that field’s range, so a fractional or oversized value is refused rather than silently truncated.
§Arguments
name- the field name.index- the element to write, or0for a scalar field.value- the value to store.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldIndexOutOfRange if the element is past the end of an array,
and MavlinkError::ValueOutOfRange if an integer field is given a value that is
fractional, infinite, not a number, or outside the range its width holds.
Sourcepub fn get_bytes(&self, name: &str, out: &mut [u8]) -> Result<usize>
pub fn get_bytes(&self, name: &str, out: &mut [u8]) -> Result<usize>
Copies the raw bytes of a byte-wide array field out.
§Arguments
name- the field name.out- the destination, which must be at least the field’s length.
§Returns
The number of bytes written, which is the field’s declared length.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldTypeMismatch if the field is not an array of char,
uint8_t, or int8_t, and MavlinkError::PayloadTooLong if out is too small.
Sourcepub fn set_bytes(&mut self, name: &str, bytes: &[u8]) -> Result<()>
pub fn set_bytes(&mut self, name: &str, bytes: &[u8]) -> Result<()>
Writes the raw bytes of a byte-wide array field, zero-padding the rest.
§Arguments
name- the field name.bytes- the bytes to store, at most the field’s declared length.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldTypeMismatch if the field is not an array of char,
uint8_t, or int8_t, and MavlinkError::PayloadTooLong if the bytes are
longer than the field.
Sourcepub fn text(&self, name: &str) -> Result<&str>
pub fn text(&self, name: &str) -> Result<&str>
Reads a char array as text, stopping at the padding.
MAVLink carries a string in a fixed-length char array, padded with zeros when the
text is shorter and left unterminated when it exactly fills the field.
§Arguments
name- the field name.
§Returns
The text, without its padding.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldTypeMismatch if the field is not a char array, and
MavlinkError::BadPayload if the bytes are not valid UTF-8.
§Examples
use pamoja_mavlink::dialect::{descriptor, DynamicMessage};
let shape = descriptor(253).expect("STATUSTEXT is in the common dialect");
let mut status = DynamicMessage::new(shape)?;
status.set_text("text", "preflight checks passed")?;
assert_eq!(status.text("text")?, "preflight checks passed");Sourcepub fn set_text(&mut self, name: &str, text: &str) -> Result<()>
pub fn set_text(&mut self, name: &str, text: &str) -> Result<()>
Writes text into a char array, padding the rest with zeros.
§Arguments
name- the field name.text- the text to store, at most the field’s declared length.
§Errors
Returns MavlinkError::UnknownField if the message has no such field,
MavlinkError::FieldTypeMismatch if the field is not a char array, and
MavlinkError::PayloadTooLong if the text is longer than the field.
Trait Implementations§
Source§impl<'a> Clone for DynamicMessage<'a>
impl<'a> Clone for DynamicMessage<'a>
Source§fn clone(&self) -> DynamicMessage<'a>
fn clone(&self) -> DynamicMessage<'a>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more