use mtp::codec::{CommunicationValue, DataValue}; use mtp::type_map::DataTypeId; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum MtpFieldError { MissingId, MissingSender, MissingReceiver, } impl std::fmt::Display for MtpFieldError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { Self::MissingId => "missing message id", Self::MissingSender => "missing sender", Self::MissingReceiver => "missing receiver", }) } } impl std::error::Error for MtpFieldError {} pub trait RequiredCommunicationFields { fn require_id(&self) -> Result; fn require_sender(&self) -> Result; fn require_receiver(&self) -> Result; } impl RequiredCommunicationFields for CommunicationValue { fn require_id(&self) -> Result { self.id().ok_or(MtpFieldError::MissingId) } fn require_sender(&self) -> Result { self.sender().ok_or(MtpFieldError::MissingSender) } fn require_receiver(&self) -> Result { self.receiver().ok_or(MtpFieldError::MissingReceiver) } } pub trait OptionalDataValueExt<'a> { fn as_bool(self) -> Option; fn as_str(self) -> Option<&'a str>; fn as_string(self) -> Option; fn as_number(self) -> Option; fn as_signed_number(self) -> Option; fn as_array(self) -> Option>; fn as_container(self) -> Option>; } impl<'a> OptionalDataValueExt<'a> for Option<&'a DataValue> { fn as_bool(self) -> Option { self.and_then(DataValue::as_bool) } fn as_str(self) -> Option<&'a str> { self.and_then(DataValue::as_str) } fn as_string(self) -> Option { self.and_then(DataValue::as_string) } fn as_number(self) -> Option { self.and_then(DataValue::as_number) } fn as_signed_number(self) -> Option { self.and_then(DataValue::as_signed_number) } fn as_array(self) -> Option> { self.and_then(DataValue::as_array) } fn as_container(self) -> Option> { self.and_then(DataValue::as_container) } } #[cfg(test)] mod tests { use super::{MtpFieldError, RequiredCommunicationFields}; use mtp::codec::{CommunicationType, CommunicationValue}; #[test] fn missing_routing_fields_are_reported_instead_of_defaulted() { let message = CommunicationValue::new(CommunicationType::Success).without_id(); assert_eq!(message.require_id(), Err(MtpFieldError::MissingId)); assert_eq!(message.require_sender(), Err(MtpFieldError::MissingSender)); assert_eq!( message.require_receiver(), Err(MtpFieldError::MissingReceiver) ); } #[test] fn present_routing_fields_are_returned_unchanged() { let message = CommunicationValue::new(CommunicationType::Success) .with_id(7) .with_sender(8) .with_receiver(9); assert_eq!(message.require_id(), Ok(7)); assert_eq!(message.require_sender(), Ok(8)); assert_eq!(message.require_receiver(), Ok(9)); } }