use std::convert::From;
use std::fmt;
use std::result::Result as StdResult;
use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Visitor, Error as SerdeError};
use crate::Event;
use crate::boxes::ByteBox;
use crate::errors::SaltyError;
use crate::tasks::TaskMessage;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Role {
Initiator,
Responder,
}
impl Role {
pub fn is_initiator(self) -> bool {
self == Role::Initiator
}
pub fn is_responder(self) -> bool {
self == Role::Responder
}
}
impl fmt::Display for Role {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Role::Initiator => write!(f, "Initiator"),
Role::Responder => write!(f, "Responder"),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) enum Identity {
Server,
Initiator,
Responder(u8),
}
impl From<Address> for Identity {
fn from(val: Address) -> Self {
match val.0 {
0x00 => Identity::Server,
0x01 => Identity::Initiator,
addr => Identity::Responder(addr),
}
}
}
impl fmt::Display for Identity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Identity::Initiator => write!(f, "initiator"),
Identity::Responder(id) => write!(f, "responder {:#04x}", id),
Identity::Server => write!(f, "server"),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) enum ClientIdentity {
Unknown,
Initiator,
Responder(u8),
}
impl fmt::Display for ClientIdentity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ClientIdentity::Unknown => write!(f, "unknown"),
ClientIdentity::Initiator => write!(f, "initiator"),
ClientIdentity::Responder(ref val) => write!(f, "responder {:#04x}", val),
}
}
}
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
pub(crate) struct Address(pub(crate) u8);
impl Address {
pub(crate) fn is_server(self) -> bool {
self.0 == 0x00
}
pub(crate) fn is_unknown(self) -> bool {
self.0 == 0x00
}
pub(crate) fn is_initiator(self) -> bool {
self.0 == 0x01
}
pub(crate) fn is_responder(self) -> bool {
self.0 >= 0x02
}
}
impl fmt::Display for Address {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:#04x}", self.0)
}
}
impl fmt::Debug for Address {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Address({:#04x})", self.0)
}
}
impl From<ClientIdentity> for Address {
fn from(val: ClientIdentity) -> Self {
Address(match val {
ClientIdentity::Unknown => 0x00,
ClientIdentity::Initiator => 0x01,
ClientIdentity::Responder(address) => {
assert!(address > 0x01, "address <= 0x01");
address
},
})
}
}
impl From<Identity> for Address {
fn from(val: Identity) -> Self {
Address(match val {
Identity::Server => 0x00,
Identity::Initiator => 0x01,
Identity::Responder(address) => {
assert!(address > 0x01, "address <= 0x01");
address
},
})
}
}
impl From<u8> for Address {
fn from(val: u8) -> Self {
Address(val)
}
}
impl Serialize for Address {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
serializer.serialize_u8(self.0)
}
}
struct AddressVisitor;
impl<'de> Visitor<'de> for AddressVisitor {
type Value = Address;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an address byte")
}
fn visit_u8<E>(self, v: u8) -> StdResult<Self::Value, E> where E: SerdeError {
Ok(Address(v))
}
}
impl<'de> Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
where D: Deserializer<'de> {
deserializer.deserialize_u8(AddressVisitor)
}
}
#[must_use]
#[derive(Debug, PartialEq)]
pub(crate) enum HandleAction {
Reply(ByteBox),
HandshakeError(SaltyError),
HandshakeDone,
Event(Event),
TaskMessage(TaskMessage),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn client_identity_into_address() {
let unknown = ClientIdentity::Unknown;
let initiator = ClientIdentity::Initiator;
let responder = ClientIdentity::Responder(0x13);
assert_eq!(Address::from(unknown), Address(0x00));
assert_eq!(Address::from(initiator), Address(0x01));
assert_eq!(Address::from(responder), Address(0x13));
}
#[test]
#[should_panic(expected = "address <= 0x01")]
fn client_identity_invalid_responder_into_address() {
let responder_invalid = ClientIdentity::Responder(0x01);
let _: Address = responder_invalid.into();
}
#[test]
fn address_display() {
assert_eq!(format!("{}", Address(0)), "0x00");
assert_eq!(format!("{}", Address(3)), "0x03");
assert_eq!(format!("{}", Address(255)), "0xff");
}
#[test]
fn client_identity_display() {
let unknown = ClientIdentity::Unknown;
let initiator = ClientIdentity::Initiator;
let responder = ClientIdentity::Responder(10);
assert_eq!(format!("{}", unknown), "unknown");
assert_eq!(format!("{}", initiator), "initiator");
assert_eq!(format!("{}", responder), "responder 0x0a");
}
}