sim_lib_stream_host/
registry.rs1use std::{collections::BTreeMap, sync::Arc};
4
5use sim_kernel::{Error, Expr, Result, Symbol};
6
7use crate::{
8 HostBackend, HostDeviceInventory, HostOpenStream, HostStreamConfigRequest,
9 missing_capability_card_expr,
10};
11
12#[derive(Default)]
14pub struct HostBackendRegistry {
15 backends: BTreeMap<Symbol, Arc<dyn HostBackend>>,
16}
17
18impl HostBackendRegistry {
19 pub fn new() -> Self {
21 Self::default()
22 }
23
24 pub fn register<B>(&mut self, backend: B) -> Result<()>
26 where
27 B: HostBackend + 'static,
28 {
29 self.register_arc(Arc::new(backend))
30 }
31
32 pub fn register_arc(&mut self, backend: Arc<dyn HostBackend>) -> Result<()> {
34 let id = backend.info().id().clone();
35 if self.backends.contains_key(&id) {
36 return Err(Error::Eval(format!(
37 "stream host backend {id} is already registered"
38 )));
39 }
40 self.backends.insert(id, backend);
41 Ok(())
42 }
43
44 pub fn backend(&self, id: &Symbol) -> Option<Arc<dyn HostBackend>> {
46 self.backends.get(id).cloned()
47 }
48
49 pub fn enumerate(&self) -> Result<Vec<HostDeviceInventory>> {
51 self.backends
52 .values()
53 .map(|backend| backend.enumerate())
54 .collect()
55 }
56
57 pub fn open(&self, request: HostStreamConfigRequest) -> Result<HostOpenStream> {
59 let backend = self.backends.get(request.backend()).ok_or_else(|| {
60 Error::Eval(format!(
61 "stream host backend {} is not registered",
62 request.backend()
63 ))
64 })?;
65 backend.open(request)
66 }
67
68 pub fn card_exprs(&self) -> Result<Vec<Expr>> {
70 let mut cards = Vec::new();
71 for backend in self.backends.values() {
72 cards.push(backend.info().card_expr());
73 cards.extend(backend.enumerate()?.card_exprs());
74 }
75 Ok(cards)
76 }
77
78 pub fn missing_capability_card(
80 &self,
81 backend: &Symbol,
82 capability: crate::HostBackendCapability,
83 ) -> Expr {
84 missing_capability_card_expr(backend, capability)
85 }
86}