use crate::envelope::{SignedEnvelope, Did};
use crate::runtime::transport::interface::{Transport, DEFAULT_PAYLOAD_CAPACITY};
use crate::config::modes::layer_kinds;
use crate::runtime::RoutingTable;
use std::sync::{Arc, Mutex};
use std::collections::{VecDeque, HashMap};
#[derive(Debug, Default)]
struct MockBus {
inboxes: Mutex<HashMap<[u8; 32], VecDeque<SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>>>>,
}
impl MockBus {
fn push(&self, env: SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>) {
if let Ok(mut map) = self.inboxes.lock() {
map.entry(env.header.recipient_did.0)
.or_default()
.push_back(env);
}
}
fn pop_for(&self, did: &Did) -> Option<SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>> {
self.inboxes.lock().ok()?.get_mut(&did.0)?.pop_front()
}
}
fn global_bus() -> &'static MockBus {
use std::sync::OnceLock;
static BUS: OnceLock<MockBus> = OnceLock::new();
BUS.get_or_init(MockBus::default)
}
#[derive(Debug, Clone)]
pub struct MockTransport {
kind: &'static str,
local_did: Did,
#[allow(dead_code)]
routing: Arc<RoutingTable>,
}
impl MockTransport {
pub fn new(routing: Arc<RoutingTable>) -> Self {
MockTransport {
kind: layer_kinds::MOCK_TRANSPORT,
local_did: Did([0u8; 32]),
routing,
}
}
pub fn with_did(mut self, did: Did) -> Self {
self.local_did = did;
self
}
}
impl Transport for MockTransport {
fn receive(&self) -> Option<SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>> {
global_bus().pop_for(&self.local_did)
}
fn send(&self, envelope: &SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>) -> Result<(), String> {
global_bus().push(*envelope);
Ok(())
}
fn kind(&self) -> &'static str {
self.kind
}
}