use std::collections::BTreeMap;
use crate::core::ConfigFeatureWarning;
#[cfg(any(feature = "rpc", feature = "discovery-etcd"))]
use crate::core::CoreError;
mod database;
mod etcd;
mod rpc;
pub use database::{DatabaseKindSection, DatabaseSection};
pub use etcd::{EtcdAuthSection, EtcdBackoffSection, EtcdDiscoverySection};
pub use rpc::{
RpcClientProvider, RpcClientSection, RpcDeadlineSection, RpcLoadBalancePolicySection,
RpcLoadBalanceSection, RpcRetrySection, RpcStreamingSection,
};
pub type RpcClientsConfig = BTreeMap<String, RpcClientSection>;
pub fn dependency_feature_warnings(
rpc_clients: &RpcClientsConfig,
database: Option<&DatabaseSection>,
) -> Vec<ConfigFeatureWarning> {
let mut warnings = Vec::new();
if !rpc_clients.is_empty() && !cfg!(feature = "rpc") {
warnings.push(ConfigFeatureWarning::ignored("rpc_clients", "rpc"));
}
if rpc_clients
.values()
.any(|client| client.provider == RpcClientProvider::Etcd)
&& !cfg!(feature = "discovery-etcd")
{
warnings.push(ConfigFeatureWarning::ignored(
"rpc_clients.*.etcd",
"discovery-etcd",
));
}
if let Some(database) = database {
let required_feature = match database.kind {
DatabaseKindSection::Sqlite if !cfg!(feature = "db-sqlite") => Some("db-sqlite"),
DatabaseKindSection::Postgres if !cfg!(feature = "db-postgres") => Some("db-postgres"),
DatabaseKindSection::Mysql if !cfg!(feature = "db-mysql") => Some("db-mysql"),
_ => None,
};
if let Some(required_feature) = required_feature {
warnings.push(ConfigFeatureWarning::ignored(
"database.kind",
required_feature,
));
}
}
warnings
}
#[cfg(any(feature = "rpc", feature = "discovery-etcd"))]
fn config_error(message: impl Into<String>) -> CoreError {
config::ConfigError::Message(message.into()).into()
}
#[cfg(test)]
mod tests {
use super::{DatabaseKindSection, DatabaseSection, RpcClientProvider, RpcClientSection};
#[test]
fn default_rpc_client_is_static_without_endpoint() {
let client = RpcClientSection::default();
assert_eq!(client.provider, RpcClientProvider::Static);
assert!(client.endpoint.is_empty());
assert!(client.retry.enabled);
}
#[test]
fn database_defaults_to_sqlite_memory() {
let database = DatabaseSection::default();
assert_eq!(database.kind, DatabaseKindSection::Sqlite);
assert_eq!(database.url, "sqlite::memory:");
}
#[cfg(feature = "rpc")]
#[test]
fn maps_rpc_client_runtime_config() {
let client = RpcClientSection {
endpoint: "http://127.0.0.1:50051".to_string(),
service: "hello-rpc".to_string(),
..RpcClientSection::default()
};
let config = client.to_rpc_client_config().expect("rpc client config");
assert_eq!(config.endpoint, "http://127.0.0.1:50051");
assert_eq!(config.discovery.service.as_deref(), Some("hello-rpc"));
assert!(config.retry.enabled);
}
}