use crate::error::{Error, Result};
use sn_messaging::EndUser;
use std::{
collections::{btree_map::Entry, BTreeMap},
net::SocketAddr,
};
use xor_name::{Prefix, XorName};
pub type SocketId = XorName;
pub(crate) struct EndUserRegistry {
clients: BTreeMap<SocketAddr, EndUser>,
socket_id_mapping: BTreeMap<SocketId, SocketAddr>,
}
impl EndUserRegistry {
pub fn new() -> Self {
Self {
clients: BTreeMap::default(),
socket_id_mapping: BTreeMap::default(),
}
}
pub fn get_enduser_by_addr(&self, socketaddr: &SocketAddr) -> Option<&EndUser> {
self.clients.get(socketaddr)
}
pub fn get_socket_addr(&self, socket_id: SocketId) -> Option<&SocketAddr> {
self.socket_id_mapping.get(&socket_id)
}
pub fn try_add(&mut self, sender: SocketAddr, section_prefix: &Prefix) -> Result<EndUser> {
let socket_id = XorName::from_content(&[
&bincode::serialize(&sender).map_err(|_| Error::FailedSignature)?
]);
let user_xorname = section_prefix.substituted_in(socket_id);
let end_user = EndUser {
xorname: user_xorname,
socket_id,
};
match self.socket_id_mapping.entry(socket_id) {
Entry::Vacant(entry) => {
let _ = self.clients.insert(sender, end_user);
let _ = entry.insert(sender);
}
Entry::Occupied(_) => (),
}
Ok(end_user)
}
}