#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::protocol::traits::{Buildable, Builder};
use crate::protocol::{MavType, Units, Value};
use super::message_field_invalid_value::MessageFieldInvalidValue;
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MessageField {
name: String,
description: String,
r#type: MavType,
r#enum: Option<String>,
units: Option<Units>,
bitmask: bool,
print_format: Option<String>,
default: Option<Value>,
invalid: Option<MessageFieldInvalidValue>,
instance: bool,
extension: bool,
}
impl Buildable for MessageField {
type Builder = MessageFieldBuilder;
fn to_builder(&self) -> MessageFieldBuilder {
MessageFieldBuilder {
field: self.clone(),
}
}
}
impl MessageField {
pub fn builder() -> MessageFieldBuilder {
MessageFieldBuilder::new()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn description(&self) -> &str {
&self.description
}
pub fn r#type(&self) -> &MavType {
&self.r#type
}
pub fn r#enum(&self) -> Option<&str> {
match &self.r#enum {
None => None,
Some(enm) => Some(enm.as_str()),
}
}
pub fn units(&self) -> Option<&Units> {
match &self.units {
None => None,
Some(units) => Some(units),
}
}
pub fn bitmask(&self) -> bool {
self.bitmask
}
pub fn print_format(&self) -> Option<&str> {
self.print_format.as_deref()
}
pub fn default(&self) -> Option<&Value> {
self.default.as_ref()
}
pub fn invalid(&self) -> Option<&MessageFieldInvalidValue> {
self.invalid.as_ref()
}
pub fn instance(&self) -> bool {
self.instance
}
pub fn extension(&self) -> bool {
self.extension
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MessageFieldBuilder {
field: MessageField,
}
impl Builder for MessageFieldBuilder {
type Buildable = MessageField;
fn build(&self) -> MessageField {
#[allow(clippy::match_single_binding)]
match self.field.clone() {
MessageField {
name,
description,
r#type,
r#enum,
units,
bitmask,
print_format,
default,
invalid,
instance,
extension,
} => MessageField {
name,
description,
r#type,
r#enum,
units,
bitmask,
print_format,
default,
invalid,
instance,
extension,
},
}
}
}
impl MessageFieldBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn set_name(&mut self, name: String) -> &mut Self {
self.field.name = name;
self
}
pub fn set_description(&mut self, description: String) -> &mut Self {
self.field.description = description;
self
}
pub fn set_type(&mut self, r#type: MavType) -> &mut Self {
self.field.r#type = r#type;
self
}
pub fn set_enum(&mut self, r#enum: Option<String>) -> &mut Self {
self.field.r#enum = r#enum;
self
}
pub fn set_units(&mut self, units: Option<Units>) -> &mut Self {
self.field.units = units;
self
}
pub fn set_bitmask(&mut self, bitmask: bool) -> &mut Self {
self.field.bitmask = bitmask;
self
}
pub fn set_print_format(&mut self, print_format: Option<String>) -> &mut Self {
self.field.print_format = print_format;
self
}
pub fn set_default(&mut self, default: Option<Value>) -> &mut Self {
self.field.default = default;
self
}
pub fn set_invalid(&mut self, invalid: Option<MessageFieldInvalidValue>) -> &mut Self {
self.field.invalid = invalid;
self
}
pub fn set_instance(&mut self, instance: bool) -> &mut Self {
self.field.instance = instance;
self
}
pub fn set_extension(&mut self, extension: bool) -> &mut Self {
self.field.extension = extension;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn message_field_builder() {
let field = MessageFieldBuilder::new()
.set_name("name".to_string())
.set_description("description".to_string())
.set_type(MavType::Float)
.set_enum(Some("MAV_CMD".to_string()))
.set_units(Some(Units::Ampere))
.set_bitmask(true)
.set_print_format(Some("format".to_string()))
.set_default(Some(Value::UInt16(u16::MAX)))
.set_invalid(Some(MessageFieldInvalidValue::Value(Value::Max(
MavType::Float,
))))
.set_instance(true)
.set_extension(true)
.build();
assert!(matches!(field, MessageField { .. }));
assert_eq!(field.name(), "name");
assert_eq!(field.description(), "description");
assert!(matches!(field.r#type(), MavType::Float));
assert_eq!(field.r#enum.clone().unwrap(), "MAV_CMD");
assert!(matches!(field.units(), Some(Units::Ampere)));
assert!(field.bitmask());
assert_eq!(field.print_format.clone().unwrap(), "format");
assert!(matches!(field.default, Some(Value::UInt16(u16::MAX))));
assert!(matches!(
field.invalid(),
Some(MessageFieldInvalidValue::Value(Value::Max(MavType::Float,)))
));
assert!(field.instance());
assert!(field.extension());
}
}