use std::sync::Arc;
use nest_rs_config::ConfigModule;
use nest_rs_core::{ContainerBuilder, DynamicModule};
use nest_rs_throttler::{ThrottlerConfig, ThrottlerStore};
use crate::QueueConnection;
use crate::throttler::RedisThrottler;
pub struct RedisThrottlerModule;
impl RedisThrottlerModule {
pub fn for_root(config: impl Into<Option<ThrottlerConfig>>) -> RedisThrottlerSetup {
RedisThrottlerSetup {
pinned: config.into(),
}
}
}
pub struct RedisThrottlerSetup {
pinned: Option<ThrottlerConfig>,
}
impl DynamicModule for RedisThrottlerSetup {
fn collect(&self, builder: ContainerBuilder) -> ContainerBuilder {
let builder = ConfigModule::provide_feature(self.pinned.clone(), builder);
builder.provide_factory::<Arc<dyn ThrottlerStore>, _, _>(|container| async move {
let config = container
.get::<ThrottlerConfig>()
.expect("ThrottlerConfig is resolved by ConfigModule::provide_feature");
let (default, trusted_proxies) = nest_rs_throttler::resolve(&config)?;
let conn = container.get::<QueueConnection>().expect(
"QueueConnection is resolved by QueueModule — import QueueModule::for_root \
before RedisThrottlerModule::for_root",
);
Ok(Arc::new(RedisThrottler::new(
(*conn).clone(),
default,
trusted_proxies,
)) as Arc<dyn ThrottlerStore>)
})
}
}