use std::collections::HashSet;
use vyre_foundation::ir::OpId;
use super::grid_sync_split::wrap_grid_sync_split;
use crate::backend::{BackendError, VyreBackend};
pub struct BackendRegistration {
pub id: &'static str,
pub factory: fn() -> Result<Box<dyn VyreBackend>, BackendError>,
pub supported_ops: fn() -> &'static HashSet<OpId>,
}
impl BackendRegistration {
pub fn acquire(&self) -> Result<Box<dyn VyreBackend>, BackendError> {
(self.factory)().map(wrap_grid_sync_split)
}
}
inventory::collect!(BackendRegistration);
pub struct BackendPrecedence {
pub id: &'static str,
pub rank: u32,
}
inventory::collect!(BackendPrecedence);
pub struct BackendCapability {
pub id: &'static str,
pub dispatches: bool,
}
inventory::collect!(BackendCapability);
#[must_use]
pub fn registered_backends() -> &'static [&'static BackendRegistration] {
static FROZEN: std::sync::OnceLock<Box<[&'static BackendRegistration]>> =
std::sync::OnceLock::new();
FROZEN.get_or_init(|| {
let registration_count = inventory::iter::<BackendRegistration>.into_iter().count();
let mut registrations = Vec::new();
registrations
.try_reserve_exact(registration_count)
.unwrap_or_else(|error| {
panic!(
"Vyre backend inventory could not reserve {registration_count} registration slot(s): {error}. Fix: reduce linked backend inventory or split registry initialization."
)
});
registrations.extend(inventory::iter::<BackendRegistration>);
registrations.into_boxed_slice()
})
}