diff --git a/src/service/client/mod.rs b/src/service/client/mod.rs index cc8d52d1af12a1c5e5e74f309622cdd6e2d26405..03b0a14252e7775a46f72b73ff522e89fcd9bd35 100644 --- a/src/service/client/mod.rs +++ b/src/service/client/mod.rs @@ -18,9 +18,7 @@ pub struct Service { impl crate::Service for Service { fn build(args: crate::Args<'_>) -> Result<Arc<Self>> { let config = &args.server.config; - let resolver = args - .get_service::<resolver::Service>("resolver") - .expect("resolver must be built prior to client"); + let resolver = args.require_service::<resolver::Service>("resolver"); Ok(Arc::new(Self { default: base(config) diff --git a/src/service/service.rs b/src/service/service.rs index 99b8723a0ebbe92b19e1068784413851c1a40a25..863b955b533d76cc75acda6f124ad95e6e6f6f29 100644 --- a/src/service/service.rs +++ b/src/service/service.rs @@ -1,7 +1,7 @@ use std::{any::Any, collections::BTreeMap, fmt::Write, sync::Arc}; use async_trait::async_trait; -use conduit::{utils::string::split_once_infallible, Result, Server}; +use conduit::{err, error::inspect_log, utils::string::split_once_infallible, Err, Result, Server}; use database::Database; #[async_trait] @@ -44,9 +44,26 @@ pub(crate) struct Args<'a> { pub(crate) type MapVal = (Arc<dyn Service>, Arc<dyn Any + Send + Sync>); impl Args<'_> { - pub(crate) fn get_service<T: Any + Send + Sync>(&self, name: &str) -> Option<Arc<T>> { - get::<T>(self.service, name) + pub(crate) fn require_service<T: Any + Send + Sync>(&self, name: &str) -> Arc<T> { + self.try_get_service::<T>(name) + .inspect_err(inspect_log) + .expect("Failure to reference service required by another service.") } + + pub(crate) fn try_get_service<T: Any + Send + Sync>(&self, name: &str) -> Result<Arc<T>> { + try_get::<T>(self.service, name) + } +} + +pub(crate) fn try_get<T: Any + Send + Sync>(map: &Map, name: &str) -> Result<Arc<T>> { + map.get(name).map_or_else( + || Err!("Service {name:?} does not exist or has not been built yet."), + |(_, s)| { + s.clone() + .downcast::<T>() + .map_err(|_| err!("Service {name:?} must be correctly downcast.")) + }, + ) } pub(crate) fn get<T: Any + Send + Sync>(map: &Map, name: &str) -> Option<Arc<T>> { diff --git a/src/service/services.rs b/src/service/services.rs index d0f74e13ae4e3b9571c6ded98cfbe796f1a21c38..136059cdc3ee3f22afa090c17dff5706c66283a7 100644 --- a/src/service/services.rs +++ b/src/service/services.rs @@ -173,5 +173,17 @@ fn interrupt(&self) { } } - pub fn get<T: Any + Send + Sync>(&self, name: &str) -> Option<Arc<T>> { service::get::<T>(&self.service, name) } + pub fn try_get<T>(&self, name: &str) -> Result<Arc<T>> + where + T: Any + Send + Sync, + { + service::try_get::<T>(&self.service, name) + } + + pub fn get<T>(&self, name: &str) -> Option<Arc<T>> + where + T: Any + Send + Sync, + { + service::get::<T>(&self.service, name) + } }