use crate::compat::vec::Vec;
use crate::errcode::{Kind, Origin};
use crate::{
Error, LocalInfo, LocalInfoIdentifier, LocalMessage, Result, SECURE_CHANNEL_IDENTIFIER,
};
pub struct SecureChannelLocalInfo {
their_identifier: LocalInfoIdentifier,
}
impl SecureChannelLocalInfo {
pub fn their_identifier(&self) -> LocalInfoIdentifier {
self.their_identifier.clone()
}
}
impl SecureChannelLocalInfo {
#[track_caller]
fn error_type_id() -> Error {
Error::new(
Origin::Identity,
Kind::Invalid,
"invalid local info identifier for secure channel",
)
}
#[track_caller]
fn error_format() -> Error {
Error::new(
Origin::Identity,
Kind::Invalid,
"invalid format for local info identifier for secure channel",
)
}
pub fn from_local_info(value: &LocalInfo) -> Result<Self> {
if value.type_identifier() != SECURE_CHANNEL_IDENTIFIER {
return Err(Self::error_type_id());
}
match minicbor::decode::<LocalInfoIdentifier>(value.data()) {
Ok(identifier) => Ok(Self {
their_identifier: identifier,
}),
Err(_) => Err(Self::error_format()),
}
}
pub fn to_local_info(&self) -> Result<LocalInfo> {
Ok(LocalInfo::new(
SECURE_CHANNEL_IDENTIFIER.into(),
crate::cbor_encode_preallocate(&self.their_identifier)?,
))
}
pub fn find_info(local_msg: &LocalMessage) -> Result<Self> {
Self::find_info_from_list(local_msg.local_info())
}
pub fn find_info_from_list(local_info: &[LocalInfo]) -> Result<Self> {
match local_info
.iter()
.find(|x| x.type_identifier() == SECURE_CHANNEL_IDENTIFIER)
{
Some(local_info) => Self::from_local_info(local_info),
None => Err(Self::error_type_id()),
}
}
}
impl SecureChannelLocalInfo {
pub fn mark(
mut local_info: Vec<LocalInfo>,
their_identity_id: LocalInfoIdentifier,
) -> Result<Vec<LocalInfo>> {
local_info.retain(|x| x.type_identifier() != SECURE_CHANNEL_IDENTIFIER);
local_info.push(
Self {
their_identifier: their_identity_id,
}
.to_local_info()?,
);
Ok(local_info)
}
}