use crate::compat::string::{String, ToString};
use crate::errcode::{Kind, Origin};
use crate::{AddressMetadata, Error, LocalInfoIdentifier, Result, SECURE_CHANNEL_IDENTIFIER};
pub struct SecureChannelMetadata {
their_identifier: LocalInfoIdentifier,
}
impl SecureChannelMetadata {
pub fn their_identifier(&self) -> LocalInfoIdentifier {
self.their_identifier.clone()
}
}
impl SecureChannelMetadata {
#[track_caller]
fn error_type_id() -> Error {
Error::new(
Origin::Identity,
Kind::Invalid,
"invalid metadata identifier for secure channel",
)
}
#[track_caller]
fn error_format() -> Error {
Error::new(
Origin::Identity,
Kind::Invalid,
"invalid format for metadata identifier for secure channel",
)
}
pub fn from_terminal_address_metadata(terminal: &AddressMetadata) -> Result<Self> {
let identifier = if let Some(identifier) =
terminal.attributes.iter().find_map(|(key, value)| {
if key == SECURE_CHANNEL_IDENTIFIER {
Some(value.clone())
} else {
None
}
}) {
identifier
} else {
return Err(Self::error_type_id());
};
if let Ok(identifier) = hex::decode(identifier) {
match identifier.try_into() {
Ok(identifier) => Ok(Self {
their_identifier: LocalInfoIdentifier(identifier),
}),
Err(_) => Err(Self::error_format()),
}
} else {
Err(Self::error_format())
}
}
pub fn attribute(their_identifier: LocalInfoIdentifier) -> (String, String) {
(
SECURE_CHANNEL_IDENTIFIER.to_string(),
hex::encode(their_identifier.0),
)
}
}