axioval_engine/
services.rs1use std::{
4 any::{Any, TypeId},
5 collections::HashMap,
6 sync::Arc,
7};
8use thiserror::Error;
9
10#[derive(Clone, Copy, Debug, Eq, Error, PartialEq)]
12pub enum ServiceRegistryError {
13 #[error("a service of this type is already registered")]
14 Duplicate,
15}
16
17#[derive(Clone, Default)]
19pub struct ServiceRegistry {
20 entries: HashMap<TypeId, Arc<dyn Any + Send + Sync>>,
21}
22impl ServiceRegistry {
23 #[must_use]
25 pub fn new() -> Self {
26 Self::default()
27 }
28 pub fn register<T: Any + Send + Sync>(
30 &mut self,
31 service: T,
32 ) -> Result<(), ServiceRegistryError> {
33 if self.entries.contains_key(&TypeId::of::<T>()) {
34 return Err(ServiceRegistryError::Duplicate);
35 }
36 self.entries.insert(TypeId::of::<T>(), Arc::new(service));
37 Ok(())
38 }
39 pub(crate) fn replace<T: Any + Send + Sync>(&mut self, service: T) {
44 self.entries.insert(TypeId::of::<T>(), Arc::new(service));
45 }
46 pub(crate) fn len(&self) -> usize {
48 self.entries.len()
49 }
50 #[must_use]
52 pub fn get<T: Any + Send + Sync>(&self) -> Option<&T> {
53 self.entries.get(&TypeId::of::<T>())?.downcast_ref()
54 }
55}
56
57pub(crate) fn reviewable_exact_evidence(evidence: &axioval_ir::Evidence) -> bool {
64 evidence.exact && !evidence.locator.trim().is_empty()
65}