Skip to main content

aa_storage/
builtin.rs

1//! Placeholder registration of the OSS driver names.
2//!
3//! The concrete OSS backends (`memory`, `redis`, `postgres`) ship in Epic B and
4//! will register their own real factories from their own crates. Until then,
5//! [`register_builtin_drivers`] registers those names with a stub factory so the
6//! config loader recognizes them (and `aasm config validate` reports the correct
7//! set of valid names), while attempting to *build* one returns a clear
8//! "not yet implemented" error.
9
10use std::sync::Arc;
11
12use crate::factory::{
13    AuditSinkFactory, CredentialStoreFactory, LifecycleStoreFactory, PolicyStoreFactory, RateLimitCounterFactory,
14    SessionStoreFactory,
15};
16use crate::{
17    AuditSink, CredentialStore, LifecycleStore, PolicyStore, RateLimitCounter, Registry, Result, SessionStore,
18    StorageError,
19};
20
21/// The OSS driver names the loader recognizes ahead of their Epic B impls.
22const BUILTIN_DRIVERS: [&str; 3] = ["memory", "postgres", "redis"];
23
24/// A factory stand-in for an OSS driver whose backend is not implemented yet.
25///
26/// Registering it makes the driver *name* resolvable (so config validation
27/// passes and lists it among the valid names), but building it returns
28/// [`StorageError::Backend`] explaining the backend lands in Epic B.
29struct NotImplemented {
30    driver: &'static str,
31}
32
33impl NotImplemented {
34    fn unimplemented<T>(&self) -> Result<T> {
35        Err(StorageError::Backend(format!(
36            "storage driver {:?} is not implemented yet (ships in Epic B)",
37            self.driver
38        )))
39    }
40}
41
42impl PolicyStoreFactory for NotImplemented {
43    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn PolicyStore>> {
44        self.unimplemented()
45    }
46}
47
48impl AuditSinkFactory for NotImplemented {
49    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn AuditSink>> {
50        self.unimplemented()
51    }
52}
53
54impl SessionStoreFactory for NotImplemented {
55    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn SessionStore>> {
56        self.unimplemented()
57    }
58}
59
60impl CredentialStoreFactory for NotImplemented {
61    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn CredentialStore>> {
62        self.unimplemented()
63    }
64}
65
66impl RateLimitCounterFactory for NotImplemented {
67    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn RateLimitCounter>> {
68        self.unimplemented()
69    }
70}
71
72impl LifecycleStoreFactory for NotImplemented {
73    fn build(&self, _config: &toml::Value) -> Result<Arc<dyn LifecycleStore>> {
74        self.unimplemented()
75    }
76}
77
78/// Register the placeholder OSS drivers (`memory`, `redis`, `postgres`) for
79/// every storage kind.
80///
81/// This is the manual `register_drivers()`-at-boot hook the design calls for;
82/// Epic B replaces each placeholder with the real driver crate's `register`
83/// call.
84pub fn register_builtin_drivers(registry: &mut Registry) {
85    for driver in BUILTIN_DRIVERS {
86        registry.register_policy_store(driver, Box::new(NotImplemented { driver }));
87        registry.register_audit_sink(driver, Box::new(NotImplemented { driver }));
88        registry.register_session_store(driver, Box::new(NotImplemented { driver }));
89        registry.register_credential_store(driver, Box::new(NotImplemented { driver }));
90        registry.register_rate_limit_counter(driver, Box::new(NotImplemented { driver }));
91        registry.register_lifecycle_store(driver, Box::new(NotImplemented { driver }));
92    }
93}