use std::collections::HashMap;
use anyhow::Error;
use bimap::BiMap;
use once_cell::sync::Lazy;
use super::general_name::{GeneralNameTypeRegistry, GeneralNameValueType};
use crate::tables::{IntTable, TableTrait};
type GeneralNameDataTuple = (i16, GeneralNameTypeRegistry, GeneralNameValueType);
type Gntr = GeneralNameTypeRegistry;
type Gnvt = GeneralNameValueType;
#[rustfmt::skip]
const GENERAL_NAME_DATA: [GeneralNameDataTuple; 10] = [
(-3, Gntr::OtherNameBundleEID, Gnvt::Unsupported),
(-2, Gntr::OtherNameSmtpUTF8Mailbox, Gnvt::Text),
(-1, Gntr::OtherNameHardwareModuleName, Gnvt::OtherNameHWModuleName),
(0, Gntr::OtherName, Gnvt::OtherNameHWModuleName),
(1, Gntr::Rfc822Name, Gnvt::Text),
(2, Gntr::DNSName, Gnvt::Text),
(4, Gntr::DirectoryName, Gnvt::Name),
(6, Gntr::UniformResourceIdentifier, Gnvt::Text),
(7, Gntr::IPAddress, Gnvt::Bytes),
(8, Gntr::RegisteredID, Gnvt::Oid),
];
pub(crate) struct GeneralNameData {
int_to_name_table: IntegerToGNTable,
int_to_type_table: HashMap<i16, GeneralNameValueType>,
}
impl GeneralNameData {
pub(crate) fn get_int_to_name_table(&self) -> &IntegerToGNTable {
&self.int_to_name_table
}
pub(crate) fn get_int_to_type_table(&self) -> &HashMap<i16, GeneralNameValueType> {
&self.int_to_type_table
}
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct IntegerToGNTable(IntTable<GeneralNameTypeRegistry>);
impl IntegerToGNTable {
pub(crate) fn new() -> Self {
Self(IntTable::<GeneralNameTypeRegistry>::new())
}
pub(crate) fn add(&mut self, k: i16, v: GeneralNameTypeRegistry) {
self.0.add(k, v);
}
pub(crate) fn get_map(&self) -> &BiMap<i16, GeneralNameTypeRegistry> {
self.0.get_map()
}
}
static GENERAL_NAME_TABLES: Lazy<GeneralNameData> = Lazy::new(|| {
let mut int_to_name_table = IntegerToGNTable::new();
let mut int_to_type_table = HashMap::new();
for data in GENERAL_NAME_DATA {
int_to_name_table.add(data.0, data.1);
int_to_type_table.insert(data.0, data.2);
}
GeneralNameData {
int_to_name_table,
int_to_type_table,
}
});
pub(crate) fn get_gn_from_int(i: i16) -> Result<GeneralNameTypeRegistry, Error> {
GENERAL_NAME_TABLES
.get_int_to_name_table()
.get_map()
.get_by_left(&i)
.ok_or(Error::msg(format!(
"GeneralName not found in the general name registry table given int {i}"
)))
.cloned()
}
pub(crate) fn get_int_from_gn(gn: GeneralNameTypeRegistry) -> Result<i16, Error> {
GENERAL_NAME_TABLES
.get_int_to_name_table()
.get_map()
.get_by_right(&gn)
.ok_or(Error::msg(format!(
"Int value not found in the general name registry table given GeneralName {gn:?}"
)))
.cloned()
}
pub(crate) fn get_gn_value_type_from_int(i: i16) -> Result<GeneralNameValueType, Error> {
GENERAL_NAME_TABLES
.get_int_to_type_table()
.get(&i)
.ok_or(Error::msg(format!(
"General name value type not found in the general name registry table given {i}"
)))
.cloned()
}