valence_core/runtime/
builder.rs1use super::Valence;
4use crate::actor::Actor;
5use crate::backend::DatabaseBackend;
6use crate::error::{Error, Result};
7use crate::ports::actor::{ActorFactory, JsonActorFactory};
8use crate::ports::endpoints::{DatabaseEndpointResolver, NoopEndpointResolver};
9use crate::ports::secrets::{NoOpSecretProvider, SecretProvider};
10use crate::router::DatabaseRouter;
11use crate::router_key::router_key;
12use std::sync::Arc;
13use valence_telemetry::{install_telemetry_sink, NoOpSink, TelemetrySink};
14
15#[derive(Default)]
48pub struct ValenceBuilder {
49 router: DatabaseRouter,
50 injected_router: Option<Arc<DatabaseRouter>>,
51 registered_keys: Vec<String>,
52 default_backend_key: Option<String>,
53 telemetry_sink: Option<Arc<dyn TelemetrySink>>,
54 secret_provider: Option<Arc<dyn SecretProvider>>,
55 actor_factory: Option<Arc<dyn ActorFactory>>,
56 endpoint_resolver: Option<Arc<dyn DatabaseEndpointResolver>>,
57 actor: Option<Actor>,
58}
59
60impl ValenceBuilder {
61 pub fn new() -> Self {
63 Self::default()
64 }
65
66 pub fn add_backend(
80 mut self,
81 logical_name: impl AsRef<str>,
82 backend: Arc<dyn DatabaseBackend>,
83 ) -> Self {
84 let key = router_key(logical_name.as_ref(), backend.engine_id());
85 self.registered_keys.push(key.clone());
86 self.router.register(key, backend);
87 self
88 }
89
90 pub fn add_backend_key(
92 mut self,
93 key: impl Into<String>,
94 backend: Arc<dyn DatabaseBackend>,
95 ) -> Self {
96 let key = key.into();
97 self.registered_keys.push(key.clone());
98 self.router.register(key, backend);
99 self
100 }
101
102 pub fn database_router(mut self, router: Arc<DatabaseRouter>) -> Self {
106 self.injected_router = Some(router);
107 self
108 }
109
110 pub fn default_backend_key(mut self, key: impl Into<String>) -> Self {
114 self.default_backend_key = Some(key.into());
115 self
116 }
117
118 pub fn telemetry_sink(mut self, sink: Arc<dyn TelemetrySink>) -> Self {
120 self.telemetry_sink = Some(sink);
121 self
122 }
123
124 pub fn secret_provider(mut self, provider: Arc<dyn SecretProvider>) -> Self {
126 self.secret_provider = Some(provider);
127 self
128 }
129
130 pub fn actor_factory(mut self, factory: Arc<dyn ActorFactory>) -> Self {
132 self.actor_factory = Some(factory);
133 self
134 }
135
136 pub fn endpoint_resolver(mut self, resolver: Arc<dyn DatabaseEndpointResolver>) -> Self {
138 self.endpoint_resolver = Some(resolver);
139 self
140 }
141
142 pub fn with_actor(mut self, actor: Actor) -> Self {
144 self.actor = Some(actor);
145 self
146 }
147
148 pub fn build(self) -> Result<Valence> {
153 let router = if let Some(injected) = self.injected_router {
154 if self.registered_keys.is_empty() {
155 injected
156 } else {
157 return Err(Error::Internal(
158 "ValenceBuilder: use database_router() or add_backend(), not both".into(),
159 ));
160 }
161 } else {
162 if self.router.len()? == 0 {
163 return Err(Error::Internal(
164 "ValenceBuilder requires at least one backend — call add_backend() or add_backend_key()".into(),
165 ));
166 }
167 Arc::new(self.router)
168 };
169
170 let active_backend_key = match self.default_backend_key {
171 Some(key) => key,
172 None if self.registered_keys.len() == 1 => self.registered_keys[0].clone(),
173 None => {
174 return Err(Error::Internal(
175 "ValenceBuilder requires default_backend_key() when multiple backends are registered".into(),
176 ));
177 }
178 };
179
180 let telemetry_sink = match self.telemetry_sink {
181 Some(sink) => {
182 install_telemetry_sink(Arc::clone(&sink));
183 sink
184 }
185 None => Arc::new(NoOpSink),
186 };
187
188 let actor = self.actor.unwrap_or(Actor::Anonymous);
189
190 Ok(Valence {
191 router,
192 active_backend_key,
193 telemetry_sink,
194 secret_provider: self
195 .secret_provider
196 .unwrap_or_else(|| Arc::new(NoOpSecretProvider)),
197 actor_factory: self
198 .actor_factory
199 .unwrap_or_else(|| Arc::new(JsonActorFactory)),
200 endpoint_resolver: self
201 .endpoint_resolver
202 .unwrap_or_else(|| Arc::new(NoopEndpointResolver)),
203 actor,
204 owner_override: None,
205 })
206 }
207}