Skip to main content

DynamicMessage

Struct DynamicMessage 

Source
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>

Source

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.

Source

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);
Source

pub fn descriptor(&self) -> &'a MessageDescriptor<'a>

Returns the shape this message is read and written against.

§Returns

The descriptor.

Source

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.

Source

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.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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, or 0 for a scalar field.
  • value - the value to store, narrowed to single 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.

Source

pub fn set(&mut self, name: &str, index: usize, value: FieldValue) -> Result<()>

Writes a value into a field, whichever kind it is.

§Arguments
  • name - the field name.
  • index - the element to write, or 0 for a scalar field.
  • value - the value to store.
§Errors

Returns the same errors as the typed setter for the value’s kind.

Source

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, or 0 for 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.

Source

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, or 0 for 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.

Source

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.

Source

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.

Source

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");
Source

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>

Source§

fn clone(&self) -> DynamicMessage<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for DynamicMessage<'a>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for DynamicMessage<'a>

§

impl<'a> RefUnwindSafe for DynamicMessage<'a>

§

impl<'a> Send for DynamicMessage<'a>

§

impl<'a> Sync for DynamicMessage<'a>

§

impl<'a> Unpin for DynamicMessage<'a>

§

impl<'a> UnsafeUnpin for DynamicMessage<'a>

§

impl<'a> UnwindSafe for DynamicMessage<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.