#![forbid(unsafe_code)]
use crate::error::{HsmError, HsmResult};
use crate::pkcs11_abi::types::CK_SLOT_ID;
use crate::token::token::Token;
use std::collections::HashMap;
use std::sync::Arc;
pub struct SlotManager {
tokens: HashMap<CK_SLOT_ID, Arc<Token>>,
}
impl Default for SlotManager {
fn default() -> Self {
Self::new()
}
}
impl SlotManager {
pub fn new() -> Self {
let mut tokens = HashMap::new();
tokens.insert(0, Arc::new(Token::new()));
Self { tokens }
}
pub fn new_with_config(config: &crate::config::config::HsmConfig) -> Self {
let count = config.token.slot_count.max(1);
let max_slots = CK_SLOT_ID::MAX as usize;
let count = count.min(max_slots);
let mut tokens = HashMap::new();
for i in 0..count {
let slot_id = i as CK_SLOT_ID;
tokens.insert(
slot_id,
Arc::new(Token::new_with_config_for_slot(Some(config), slot_id)),
);
}
Self { tokens }
}
pub fn get_slot_ids(&self) -> Vec<CK_SLOT_ID> {
let mut ids: Vec<_> = self.tokens.keys().copied().collect();
ids.sort();
ids
}
pub fn get_token(&self, slot_id: CK_SLOT_ID) -> HsmResult<Arc<Token>> {
self.tokens
.get(&slot_id)
.cloned()
.ok_or(HsmError::SlotIdInvalid)
}
pub fn validate_slot(&self, slot_id: CK_SLOT_ID) -> HsmResult<()> {
if self.tokens.contains_key(&slot_id) {
Ok(())
} else {
Err(HsmError::SlotIdInvalid)
}
}
pub fn slot_count(&self) -> usize {
self.tokens.len()
}
}