use crate::errors::{parity, Error, MessageError, Result, SubsystemError, TerminalError};
use crate::fields::*;
use crate::{flags::*, Header, Word};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CommandWord {
data: [u8; 2],
parity: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StatusWord {
data: [u8; 2],
parity: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DataWord {
data: [u8; 2],
parity: u8,
}
impl CommandWord {
pub fn address(&self) -> Address {
COMMAND_ADDRESS_FIELD.get(self)
}
pub fn set_address(&mut self, value: Address) {
COMMAND_ADDRESS_FIELD.set(self, value.into());
}
pub fn with_address(mut self, value: Address) -> Self {
self.set_address(value);
self
}
pub fn subaddress(&self) -> SubAddress {
COMMAND_SUBADDRESS_FIELD.get(self)
}
pub fn set_subaddress(&mut self, value: SubAddress) {
COMMAND_SUBADDRESS_FIELD.set(self, value.into());
}
pub fn with_subaddress(mut self, value: SubAddress) -> Self {
self.set_subaddress(value);
self
}
pub fn transmit_receive(&self) -> TransmitReceive {
COMMAND_TRANSMIT_RECEIVE_FIELD.get(self)
}
pub fn set_transmit_receive(&mut self, value: TransmitReceive) {
COMMAND_TRANSMIT_RECEIVE_FIELD.set(self, value.into());
}
pub fn with_transmit_receive(mut self, value: TransmitReceive) -> Self {
self.set_transmit_receive(value);
self
}
pub fn mode_code(&self) -> ModeCode {
COMMAND_MODE_CODE_FIELD.get(self)
}
pub fn set_mode_code(&mut self, value: ModeCode) {
COMMAND_MODE_CODE_FIELD.set(self, value.into());
}
pub fn with_mode_code(mut self, value: ModeCode) -> Self {
self.set_mode_code(value);
self
}
pub fn word_count(&self) -> u8 {
match COMMAND_WORD_COUNT_FIELD.get(self) {
0 => 32u8,
k => k as u8,
}
}
pub fn set_word_count(&mut self, mut value: u8) {
if value > 31 {
value = 0;
}
COMMAND_WORD_COUNT_FIELD.set(self, value);
}
pub fn with_word_count(mut self, value: u8) -> Self {
self.set_word_count(value);
self
}
#[must_use = "Returned value is not used"]
pub fn is_mode_code(&self) -> bool {
self.subaddress().is_mode_code()
}
#[must_use = "Returned value is not used"]
pub fn is_transmit(&self) -> bool {
self.transmit_receive().is_transmit()
}
#[must_use = "Returned value is not used"]
pub fn is_receive(&self) -> bool {
self.transmit_receive().is_receive()
}
#[must_use = "Returned value is not used"]
pub fn count(&self) -> usize {
self.word_count() as usize
}
}
impl StatusWord {
pub fn address(&self) -> Address {
STATUS_ADDRESS_FIELD.get(self)
}
pub fn set_address(&mut self, value: Address) {
STATUS_ADDRESS_FIELD.set(self, value.into());
}
pub fn with_address(mut self, value: Address) -> Self {
self.set_address(value);
self
}
pub fn instrumentation(&self) -> Instrumentation {
STATUS_INSTRUMENTATION_FIELD.get(self)
}
pub fn set_instrumentation(&mut self, value: Instrumentation) {
STATUS_INSTRUMENTATION_FIELD.set(self, value.into());
}
pub fn with_instrumentation(mut self, value: Instrumentation) -> Self {
self.set_instrumentation(value);
self
}
pub fn service_request(&self) -> ServiceRequest {
STATUS_SERVICE_REQUEST_FIELD.get(self)
}
pub fn set_service_request(&mut self, value: ServiceRequest) {
STATUS_SERVICE_REQUEST_FIELD.set(self, value.into());
}
pub fn with_service_request(mut self, value: ServiceRequest) -> Self {
self.set_service_request(value);
self
}
pub fn reserved(&self) -> Reserved {
STATUS_RESERVED_FIELD.get(self)
}
pub fn set_reserved(&mut self, value: Reserved) {
STATUS_RESERVED_FIELD.set(self, value.into());
}
pub fn with_reserved(mut self, value: Reserved) -> Self {
self.set_reserved(value);
self
}
pub fn broadcast_received(&self) -> BroadcastReceived {
STATUS_BROADCAST_RECEIVED_FIELD.get(self)
}
pub fn set_broadcast_received(&mut self, value: BroadcastReceived) {
STATUS_BROADCAST_RECEIVED_FIELD.set(self, value.into());
}
pub fn with_broadcast_received(mut self, value: BroadcastReceived) -> Self {
self.set_broadcast_received(value);
self
}
pub fn terminal_busy(&self) -> TerminalBusy {
STATUS_TERMINAL_BUSY_FIELD.get(self)
}
pub fn set_terminal_busy(&mut self, value: TerminalBusy) {
STATUS_TERMINAL_BUSY_FIELD.set(self, value.into());
}
pub fn with_terminal_busy(mut self, value: TerminalBusy) -> Self {
self.set_terminal_busy(value);
self
}
pub fn dynamic_bus_acceptance(&self) -> DynamicBusAcceptance {
STATUS_DYNAMIC_BUS_ACCEPTANCE_FIELD.get(self)
}
pub fn set_dynamic_bus_acceptance(&mut self, value: DynamicBusAcceptance) {
STATUS_DYNAMIC_BUS_ACCEPTANCE_FIELD.set(self, value.into());
}
pub fn with_dynamic_bus_acceptance(mut self, value: DynamicBusAcceptance) -> Self {
self.set_dynamic_bus_acceptance(value);
self
}
pub fn message_error(&self) -> MessageError {
STATUS_MESSAGE_ERROR_FIELD.get(self)
}
pub fn set_message_error(&mut self, value: MessageError) {
STATUS_MESSAGE_ERROR_FIELD.set(self, value.into());
}
pub fn with_message_error(mut self, value: MessageError) -> Self {
self.set_message_error(value);
self
}
pub fn subsystem_error(&self) -> SubsystemError {
STATUS_SUBSYSTEM_ERROR_FIELD.get(self)
}
pub fn set_subsystem_error(&mut self, value: SubsystemError) {
STATUS_SUBSYSTEM_ERROR_FIELD.set(self, value.into());
}
pub fn with_subsystem_error(mut self, value: SubsystemError) -> Self {
self.set_subsystem_error(value);
self
}
pub fn terminal_error(&self) -> TerminalError {
STATUS_TERMINAL_ERROR_FIELD.get(self)
}
pub fn set_terminal_error(&mut self, value: TerminalError) {
STATUS_TERMINAL_ERROR_FIELD.set(self, value.into());
}
pub fn with_terminal_error(mut self, value: TerminalError) -> Self {
self.set_terminal_error(value);
self
}
#[must_use = "Returned value is not used"]
pub fn is_error(&self) -> bool {
self.message_error().is_error()
|| self.subsystem_error().is_error()
|| self.terminal_error().is_error()
}
#[must_use = "Returned value is not used"]
pub fn is_busy(&self) -> bool {
self.terminal_busy().is_busy()
}
}
impl DataWord {
pub fn with_string(mut self, data: &str) -> Result<Self> {
self.set_string(data)?;
Ok(self)
}
pub fn set_string(&mut self, data: &str) -> Result<()> {
self.data = data.as_bytes().try_into().or(Err(Error::InvalidString))?;
self.parity = self.calculate_parity();
Ok(())
}
pub fn as_string(&self) -> Result<&str> {
self.try_into()
}
}
impl Header for CommandWord {
fn count(&self) -> Option<usize> {
Some(self.word_count() as usize)
}
}
impl Header for StatusWord {
fn count(&self) -> Option<usize> {
None
}
}
impl Word for CommandWord {
fn new() -> Self {
Self {
data: [0, 0],
parity: 1,
}
}
fn with_value(mut self, data: u16) -> Self {
self.set_value(data);
self
}
fn with_bytes(mut self, data: [u8; 2]) -> Self {
self.set_bytes(data);
self
}
fn with_parity(mut self, parity: u8) -> Self {
self.set_parity(parity);
self
}
fn with_calculated_parity(mut self) -> Self {
self.parity = self.calculate_parity();
self
}
fn build(self) -> Result<Self> {
if self.check_parity() {
Ok(self)
} else {
Err(Error::InvalidWord)
}
}
fn from_value(data: u16) -> Self {
Self::new().with_value(data).with_calculated_parity()
}
fn from_bytes(data: [u8; 2]) -> Self {
Self::new().with_bytes(data)
}
fn as_bytes(&self) -> [u8; 2] {
self.data
}
fn as_value(&self) -> u16 {
self.into()
}
fn set_value(&mut self, data: u16) {
self.data = data.to_be_bytes();
self.parity = self.calculate_parity();
}
fn set_bytes(&mut self, data: [u8; 2]) {
self.data = data;
self.parity = self.calculate_parity();
}
fn parity(&self) -> u8 {
self.parity
}
fn set_parity(&mut self, parity: u8) {
self.parity = parity;
}
fn calculate_parity(&self) -> u8 {
parity(self.as_value())
}
fn check_parity(&self) -> bool {
self.parity() == self.calculate_parity()
}
}
impl Word for StatusWord {
fn new() -> Self {
Self {
data: [0, 0],
parity: 1,
}
}
fn with_value(mut self, data: u16) -> Self {
self.set_value(data);
self
}
fn with_bytes(mut self, data: [u8; 2]) -> Self {
self.set_bytes(data);
self
}
fn with_parity(mut self, parity: u8) -> Self {
self.set_parity(parity);
self
}
fn with_calculated_parity(mut self) -> Self {
self.parity = self.calculate_parity();
self
}
fn build(self) -> Result<Self> {
if self.check_parity() {
Ok(self)
} else {
Err(Error::InvalidWord)
}
}
fn from_value(data: u16) -> Self {
Self::new().with_value(data)
}
fn from_bytes(data: [u8; 2]) -> Self {
Self::new().with_bytes(data)
}
fn as_bytes(&self) -> [u8; 2] {
self.data
}
fn as_value(&self) -> u16 {
self.into()
}
fn set_value(&mut self, data: u16) {
self.data = data.to_be_bytes();
self.parity = self.calculate_parity();
}
fn set_bytes(&mut self, data: [u8; 2]) {
self.data = data;
self.parity = self.calculate_parity();
}
fn parity(&self) -> u8 {
self.parity
}
fn set_parity(&mut self, parity: u8) {
self.parity = parity;
}
fn calculate_parity(&self) -> u8 {
parity(self.as_value())
}
fn check_parity(&self) -> bool {
self.parity() == self.calculate_parity()
}
}
impl Word for DataWord {
fn new() -> Self {
Self {
data: [0, 0],
parity: 1,
}
}
fn with_value(mut self, data: u16) -> Self {
self.set_value(data);
self
}
fn with_bytes(mut self, data: [u8; 2]) -> Self {
self.set_bytes(data);
self
}
fn with_parity(mut self, parity: u8) -> Self {
self.set_parity(parity);
self
}
fn with_calculated_parity(mut self) -> Self {
self.parity = self.calculate_parity();
self
}
fn build(self) -> Result<Self> {
if self.check_parity() {
Ok(self)
} else {
Err(Error::InvalidWord)
}
}
fn from_value(data: u16) -> Self {
Self::new().with_value(data)
}
fn from_bytes(data: [u8; 2]) -> Self {
Self::new().with_bytes(data)
}
fn as_bytes(&self) -> [u8; 2] {
self.data
}
fn as_value(&self) -> u16 {
self.into()
}
fn set_value(&mut self, data: u16) {
self.data = data.to_be_bytes();
self.parity = self.calculate_parity();
}
fn set_bytes(&mut self, data: [u8; 2]) {
self.data = data;
self.parity = self.calculate_parity();
}
fn parity(&self) -> u8 {
self.parity
}
fn set_parity(&mut self, parity: u8) {
self.parity = parity;
}
fn calculate_parity(&self) -> u8 {
parity(self.as_value())
}
fn check_parity(&self) -> bool {
self.parity() == self.calculate_parity()
}
}
impl Default for CommandWord {
fn default() -> Self {
Self::new()
}
}
impl Default for StatusWord {
fn default() -> Self {
Self::new()
}
}
impl Default for DataWord {
fn default() -> Self {
Self::new()
}
}
impl TryFrom<&str> for DataWord {
type Error = Error;
fn try_from(value: &str) -> Result<Self> {
Self::new()
.with_string(value)
.map(|w| w.with_calculated_parity())
}
}
impl<'a> TryFrom<&'a DataWord> for &'a str {
type Error = Error;
fn try_from(value: &'a DataWord) -> Result<Self> {
core::str::from_utf8(&value.data).or(Err(Error::InvalidString))
}
}
impl From<u16> for CommandWord {
fn from(value: u16) -> Self {
Self::from_value(value)
}
}
impl From<u16> for StatusWord {
fn from(value: u16) -> Self {
Self::from_value(value)
}
}
impl From<u16> for DataWord {
fn from(value: u16) -> Self {
Self::from_value(value)
}
}
impl From<[u8; 2]> for CommandWord {
fn from(value: [u8; 2]) -> Self {
Self::from_bytes(value)
}
}
impl From<[u8; 2]> for StatusWord {
fn from(value: [u8; 2]) -> Self {
Self::from_bytes(value)
}
}
impl From<[u8; 2]> for DataWord {
fn from(value: [u8; 2]) -> Self {
Self::from_bytes(value)
}
}
impl From<&CommandWord> for [u8; 2] {
fn from(value: &CommandWord) -> Self {
value.data
}
}
impl From<CommandWord> for [u8; 2] {
fn from(value: CommandWord) -> Self {
value.data
}
}
impl From<&StatusWord> for [u8; 2] {
fn from(value: &StatusWord) -> Self {
value.data
}
}
impl From<StatusWord> for [u8; 2] {
fn from(value: StatusWord) -> Self {
value.data
}
}
impl From<&DataWord> for [u8; 2] {
fn from(value: &DataWord) -> Self {
value.data
}
}
impl From<DataWord> for [u8; 2] {
fn from(value: DataWord) -> Self {
value.data
}
}
impl From<&CommandWord> for u16 {
fn from(value: &CommandWord) -> Self {
u16::from_be_bytes(value.data)
}
}
impl From<CommandWord> for u16 {
fn from(value: CommandWord) -> Self {
u16::from_be_bytes(value.data)
}
}
impl From<&StatusWord> for u16 {
fn from(value: &StatusWord) -> Self {
u16::from_be_bytes(value.data)
}
}
impl From<StatusWord> for u16 {
fn from(value: StatusWord) -> Self {
u16::from_be_bytes(value.data)
}
}
impl From<&DataWord> for u16 {
fn from(value: &DataWord) -> Self {
u16::from_be_bytes(value.data)
}
}
impl From<DataWord> for u16 {
fn from(value: DataWord) -> Self {
u16::from(&value)
}
}
impl From<&DataWord> for i16 {
fn from(value: &DataWord) -> Self {
u16::from(value) as i16
}
}
impl From<DataWord> for i16 {
fn from(value: DataWord) -> Self {
i16::from(&value)
}
}
impl From<&DataWord> for u32 {
fn from(value: &DataWord) -> Self {
u16::from(value) as u32
}
}
impl From<DataWord> for u32 {
fn from(value: DataWord) -> Self {
u32::from(&value)
}
}
impl From<&DataWord> for i32 {
fn from(value: &DataWord) -> Self {
u16::from(value) as i32
}
}
impl From<DataWord> for i32 {
fn from(value: DataWord) -> Self {
i32::from(&value)
}
}
impl From<&DataWord> for u64 {
fn from(value: &DataWord) -> Self {
u16::from(value) as u64
}
}
impl From<DataWord> for u64 {
fn from(value: DataWord) -> Self {
u64::from(&value)
}
}
impl From<&DataWord> for i64 {
fn from(value: &DataWord) -> Self {
u16::from(value) as i64
}
}
impl From<DataWord> for i64 {
fn from(value: DataWord) -> Self {
i64::from(&value)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_command_get_set_address() {
let value1 = Address::Broadcast(0b11111);
let value2 = Address::Value(0b10101);
let mut word = CommandWord::new().with_address(value1);
assert_eq!(word.address(), value1);
word.set_address(value2);
assert_eq!(word.address(), value2);
assert_eq!(word.as_value(), 0b1010100000000000);
}
#[test]
fn test_command_get_set_subaddress() {
let value1 = SubAddress::ModeCode(0b11111);
let value2 = SubAddress::Value(0b10101);
let mut word = CommandWord::new().with_subaddress(value1);
assert_eq!(word.subaddress(), value1);
word.set_subaddress(value2);
assert_eq!(word.subaddress(), value2);
assert_eq!(word.as_value(), 0b0000001010100000);
}
#[test]
fn test_command_get_set_transmit_receive() {
let mut word = CommandWord::new().with_transmit_receive(TransmitReceive::Receive);
assert!(word.transmit_receive().is_receive());
word.set_transmit_receive(TransmitReceive::Transmit);
assert!(word.transmit_receive().is_transmit());
}
#[test]
fn test_command_get_set_mode_code() {
let mut word = CommandWord::new().with_mode_code(ModeCode::TransmitVectorWord);
assert_eq!(word.mode_code(), ModeCode::TransmitVectorWord);
word.set_mode_code(ModeCode::InitiateSelfTest);
assert_eq!(word.mode_code(), ModeCode::InitiateSelfTest);
}
#[test]
fn test_command_get_set_word_count() {
let mut word = CommandWord::new().with_word_count(33);
assert_eq!(word.word_count(), 32);
word.set_word_count(5);
assert_eq!(word.word_count(), 5);
}
#[test]
fn test_command_is_mode_code() {
let mut word = CommandWord::new();
word.set_subaddress(SubAddress::ModeCode(0b00000));
assert!(word.is_mode_code());
word.set_subaddress(SubAddress::Value(0b01010));
assert!(!word.is_mode_code());
word.set_subaddress(SubAddress::ModeCode(0b11111));
assert!(word.is_mode_code());
}
#[test]
fn test_command_is_transmit() {
let mut word = CommandWord::new();
word.set_transmit_receive(TransmitReceive::Transmit);
assert!(word.is_transmit());
word.set_transmit_receive(TransmitReceive::Receive);
assert!(!word.is_transmit());
}
#[test]
fn test_command_is_receive() {
let mut word = CommandWord::new();
word.set_transmit_receive(TransmitReceive::Receive);
assert!(word.is_receive());
word.set_transmit_receive(TransmitReceive::Transmit);
assert!(!word.is_receive());
}
#[test]
fn test_command_count() {
let mut word = CommandWord::new().with_word_count(33);
assert_eq!(word.count(), 32);
word.set_word_count(5);
assert_eq!(word.count(), 5);
}
#[test]
fn test_command_roundtrip() {
let word1 = CommandWord::from_value(0b0110100001101001);
let data1 = word1.as_bytes();
let word2 = CommandWord::from_bytes(data1);
let data2 = word2.as_bytes();
assert_eq!(data1, [0b01101000, 0b01101001]);
assert_eq!(data2, [0b01101000, 0b01101001]);
assert_eq!(word1, word2);
}
#[test]
fn test_command_header_count() {
let mut word = CommandWord::new().with_word_count(33);
assert_eq!(Header::count(&word), Some(32));
word.set_word_count(5);
assert_eq!(Header::count(&word), Some(5));
}
#[test]
fn test_command_word_new() {
let word = CommandWord::new();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_command_word_value() {
let mut word = CommandWord::new().with_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
word.set_value(0b1010101010101010);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_value(), 0b1010101010101010);
word = CommandWord::from_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
}
#[test]
fn test_command_word_bytes() {
let mut word = CommandWord::new().with_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
word.set_bytes([0b10101010, 0b10101010]);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_bytes(), [0b10101010, 0b10101010]);
word = CommandWord::from_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
}
#[test]
fn test_command_word_parity() {
let mut word = CommandWord::from(0).with_parity(0);
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), false);
word.set_parity(1);
assert_eq!(word.parity, 1);
assert_eq!(word.parity(), 1);
assert_eq!(word.check_parity(), true);
word = CommandWord::from(1).with_calculated_parity();
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), true);
}
#[test]
fn test_command_word_build_success() {
let word = CommandWord::new().with_calculated_parity().build();
assert!(word.is_ok());
}
#[test]
fn test_command_word_build_fail() {
let word = CommandWord::new().with_parity(0).build();
assert!(word.is_err());
}
#[test]
fn test_command_default() {
let word = CommandWord::default();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_command_from_value() {
let word: CommandWord = 0b1010101010101010.into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_command_from_bytes() {
let word: CommandWord = [0b10101010, 0b10101010].into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_command_into_value() {
let word = CommandWord::from(0b1010101010101010);
let value = u16::from(word);
assert_eq!(value, 0b1010101010101010);
}
#[test]
fn test_command_into_bytes() {
let word = CommandWord::from(0b1010101010101010);
let bytes = <[u8; 2]>::from(word);
assert_eq!(bytes, [0b10101010, 0b10101010]);
}
#[test]
fn test_status_get_set_address() {
let item1 = Address::Broadcast(0b11111);
let item2 = Address::Value(0b10101);
let mut word = StatusWord::new().with_address(item1);
assert_eq!(word.address(), item1);
word.set_address(item2);
assert_eq!(word.address(), item2);
assert_eq!(word.as_value(), 0b1010100000000000);
}
#[test]
fn test_status_get_set_instrumentation() {
let item1 = Instrumentation::Status;
let item2 = Instrumentation::Command;
let mut word = StatusWord::new().with_instrumentation(item1);
assert_eq!(word.instrumentation(), item1);
word.set_instrumentation(item2);
assert_eq!(word.instrumentation(), item2);
}
#[test]
fn test_status_get_set_service_request() {
let item1 = ServiceRequest::NoService;
let item2 = ServiceRequest::Service;
let mut word = StatusWord::new().with_service_request(item1);
assert_eq!(word.service_request(), item1);
word.set_service_request(item2);
assert_eq!(word.service_request(), item2);
}
#[test]
fn test_status_get_set_reserved() {
let item1 = Reserved::None;
let item2 = Reserved::Value(0b111);
let mut word = StatusWord::new().with_reserved(item1);
assert_eq!(word.reserved(), item1);
word.set_reserved(item2);
assert_eq!(word.reserved(), item2);
}
#[test]
fn test_status_get_set_broadcast_received() {
let item1 = BroadcastReceived::NotReceived;
let item2 = BroadcastReceived::Received;
let mut word = StatusWord::new().with_broadcast_received(item1);
assert_eq!(word.broadcast_received(), item1);
word.set_broadcast_received(item2);
assert_eq!(word.broadcast_received(), item2);
}
#[test]
fn test_status_get_set_terminal_busy() {
let item1 = TerminalBusy::NotBusy;
let item2 = TerminalBusy::Busy;
let mut word = StatusWord::new().with_terminal_busy(item1);
assert_eq!(word.is_busy(), false);
assert_eq!(word.terminal_busy(), item1);
word.set_terminal_busy(item2);
assert_eq!(word.is_busy(), true);
assert_eq!(word.terminal_busy(), item2);
}
#[test]
fn test_status_get_set_dynamic_bus_acceptance() {
let item1 = DynamicBusAcceptance::NotAccepted;
let item2 = DynamicBusAcceptance::Accepted;
let mut word = StatusWord::new().with_dynamic_bus_acceptance(item1);
assert_eq!(word.dynamic_bus_acceptance(), item1);
word.set_dynamic_bus_acceptance(item2);
assert_eq!(word.dynamic_bus_acceptance(), item2);
}
#[test]
fn test_status_get_set_message_error() {
let item1 = MessageError::None;
let item2 = MessageError::Error;
let mut word = StatusWord::new().with_message_error(item1);
assert_eq!(word.message_error(), item1);
word.set_message_error(item2);
assert_eq!(word.message_error(), item2);
}
#[test]
fn test_status_get_set_subsystem_error() {
let item1 = SubsystemError::None;
let item2 = SubsystemError::Error;
let mut word = StatusWord::new().with_subsystem_error(item1);
assert_eq!(word.subsystem_error(), item1);
word.set_subsystem_error(item2);
assert_eq!(word.subsystem_error(), item2);
}
#[test]
fn test_status_get_set_terminal_error() {
let item1 = TerminalError::None;
let item2 = TerminalError::Error;
let mut word = StatusWord::new().with_terminal_error(item1);
assert_eq!(word.terminal_error(), item1);
word.set_terminal_error(item2);
assert_eq!(word.terminal_error(), item2);
}
#[test]
fn test_status_is_error() {
let item1 = TerminalError::Error;
let item2 = SubsystemError::Error;
let item3 = MessageError::Error;
let mut word1 = StatusWord::new();
let mut word2 = StatusWord::new();
let mut word3 = StatusWord::new();
assert!(!word1.is_error());
assert!(!word2.is_error());
assert!(!word3.is_error());
word1.set_terminal_error(item1);
word2.set_subsystem_error(item2);
word3.set_message_error(item3);
assert!(word1.is_error());
assert!(word2.is_error());
assert!(word3.is_error());
}
#[test]
fn test_status_roundtrip() {
let word1 = StatusWord::from_value(0b0110100001101001);
let data1 = word1.as_bytes();
let word2 = StatusWord::from_bytes(data1);
let data2 = word2.as_bytes();
assert_eq!(data1, [0b01101000, 0b01101001]);
assert_eq!(data2, [0b01101000, 0b01101001]);
assert_eq!(word1, word2);
}
#[test]
fn test_status_header_count() {
let word = StatusWord::new();
assert_eq!(Header::count(&word), None);
}
#[test]
fn test_status_word_new() {
let word = StatusWord::new();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_status_word_value() {
let mut word = StatusWord::new().with_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
word.set_value(0b1010101010101010);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_value(), 0b1010101010101010);
word = StatusWord::from_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
}
#[test]
fn test_status_word_bytes() {
let mut word = StatusWord::new().with_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
word.set_bytes([0b10101010, 0b10101010]);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_bytes(), [0b10101010, 0b10101010]);
word = StatusWord::from_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
}
#[test]
fn test_status_word_parity() {
let mut word = StatusWord::from(0).with_parity(0);
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), false);
word.set_parity(1);
assert_eq!(word.parity, 1);
assert_eq!(word.parity(), 1);
assert_eq!(word.check_parity(), true);
word = StatusWord::from(1).with_calculated_parity();
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), true);
}
#[test]
fn test_status_word_build_success() {
let word = StatusWord::new().with_calculated_parity().build();
assert!(word.is_ok());
}
#[test]
fn test_status_word_build_fail() {
let word = StatusWord::new().with_parity(0).build();
assert!(word.is_err());
}
#[test]
fn test_status_default() {
let word = StatusWord::default();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_status_from_value() {
let word: StatusWord = 0b1010101010101010.into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_status_from_bytes() {
let word: StatusWord = [0b10101010, 0b10101010].into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_status_into_value() {
let word = StatusWord::from(0b1010101010101010);
let value = u16::from(word);
assert_eq!(value, 0b1010101010101010);
}
#[test]
fn test_status_into_bytes() {
let word = StatusWord::from(0b1010101010101010);
let bytes = <[u8; 2]>::from(word);
assert_eq!(bytes, [0b10101010, 0b10101010]);
}
#[test]
fn test_data_get_set_string_success() {
let mut word = DataWord::new().with_string("HI").unwrap();
assert_eq!(word.as_bytes(), [0b01001000, 0b01001001]);
assert_eq!(word.as_value(), 0b0100100001001001u16);
assert_eq!(word.as_string(), Ok("HI"));
assert_eq!(word.parity(), 0);
word.set_string("NO").unwrap();
assert_eq!(word.as_bytes(), [0b01001110, 0b01001111]);
assert_eq!(word.as_value(), 0b0100111001001111);
assert_eq!(word.as_string(), Ok("NO"));
assert_eq!(word.parity(), 0);
}
#[test]
fn test_data_get_set_string_failure() {
let mut word = DataWord::new().with_string("HI").unwrap();
let result = word.set_string("TOO LONG");
assert_eq!(word.as_string(), Ok("HI"));
assert_eq!(word.parity(), 0);
assert!(result.is_err());
word.set_value(0b1111111111111111);
assert_eq!(word.as_value(), 0b1111111111111111);
assert!(word.as_string().is_err());
assert_eq!(word.parity(), 1);
}
#[test]
fn test_data_roundtrip() {
let word1 = DataWord::from_value(0b0110100001101001);
let data1 = word1.as_bytes();
let word2 = DataWord::from_bytes(data1);
let data2 = word2.as_bytes();
assert_eq!(data1, [0b01101000, 0b01101001]);
assert_eq!(data2, [0b01101000, 0b01101001]);
assert_eq!(word1, word2);
}
#[test]
fn test_data_word_new() {
let word = StatusWord::new();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_data_word_value() {
let mut word = DataWord::new().with_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
word.set_value(0b1010101010101010);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_value(), 0b1010101010101010);
word = DataWord::from_value(0b0101010101010101);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_value(), 0b0101010101010101);
}
#[test]
fn test_data_word_bytes() {
let mut word = DataWord::new().with_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
word.set_bytes([0b10101010, 0b10101010]);
assert_eq!(word.data, [0b10101010, 0b10101010]);
assert_eq!(word.as_bytes(), [0b10101010, 0b10101010]);
word = DataWord::from_bytes([0b01010101, 0b01010101]);
assert_eq!(word.data, [0b01010101, 0b01010101]);
assert_eq!(word.as_bytes(), [0b01010101, 0b01010101]);
}
#[test]
fn test_data_word_parity() {
let mut word = DataWord::from(0).with_parity(0);
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), false);
word.set_parity(1);
assert_eq!(word.parity, 1);
assert_eq!(word.parity(), 1);
assert_eq!(word.check_parity(), true);
word = DataWord::from(1).with_calculated_parity();
assert_eq!(word.parity, 0);
assert_eq!(word.parity(), 0);
assert_eq!(word.check_parity(), true);
}
#[test]
fn test_data_build_success() {
let word = DataWord::new().with_calculated_parity().build();
assert!(word.is_ok());
}
#[test]
fn test_data_build_fail() {
let word = DataWord::new().with_parity(0).build();
assert!(word.is_err());
}
#[test]
fn test_data_default() {
let word = DataWord::default();
assert_eq!(word.data, [0, 0]);
assert_eq!(word.parity, 1);
}
#[test]
fn test_data_try_from_string_success() {
let result = DataWord::try_from("HI");
assert!(result.is_ok());
}
#[test]
fn test_data_try_from_string_fail() {
let result = DataWord::try_from("TOO LONG");
assert!(result.is_err());
}
#[test]
fn test_data_from_value() {
let word: DataWord = 0b1010101010101010.into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_data_from_bytes() {
let word: DataWord = [0b10101010, 0b10101010].into();
assert_eq!(word.as_value(), 0b1010101010101010);
}
#[test]
fn test_data_into_value() {
let word = DataWord::from(0b1010101010101010);
let value = u16::from(word);
assert_eq!(value, 0b1010101010101010);
}
#[test]
fn test_data_into_bytes() {
let word = DataWord::from(0b1010101010101010);
let bytes = <[u8; 2]>::from(word);
assert_eq!(bytes, [0b10101010, 0b10101010]);
}
#[test]
fn test_data_into_u32() {
let word = DataWord::from(0b0000000010101010);
let value = u32::from(word);
assert_eq!(value, 170); }
#[test]
fn test_data_into_u64() {
let word = DataWord::from(0b0000000010101010);
let value = u64::from(word);
assert_eq!(value, 170); }
#[test]
fn test_data_into_i16() {
let word = DataWord::from(0b0000000010101010);
let value = i16::from(word);
assert_eq!(value, 170); }
#[test]
fn test_data_into_i32() {
let word = DataWord::from(0b0000000010101010);
let value = i32::from(word);
assert_eq!(value, 170); }
#[test]
fn test_data_into_i64() {
let word = DataWord::from(0b0000000010101010);
let value = i64::from(word);
assert_eq!(value, 170); }
}