Skip to main content

kellnr_http/
state.rs

1use std::sync::Arc;
2
3use axum::extract::FromRef;
4use axum_extra::extract::cookie::Key;
5use flume::Sender;
6use kellnr_common::background_tasks::BackgroundTasks;
7use kellnr_common::cratesio_prefetch_msg::CratesioPrefetchMsg;
8use kellnr_cratesio_sync::CratesioSync;
9use kellnr_db::DbProvider;
10use kellnr_db::download_counter::DownloadCounter;
11use kellnr_filter::{DownloadFilters, IndexFilters};
12use kellnr_settings::{Settings, SettingsProv};
13use kellnr_storage::cratesio_crate_storage::CratesIoCrateStorage;
14use kellnr_storage::docs_storage::DocsStorage;
15use kellnr_storage::kellnr_crate_storage::KellnrCrateStorage;
16use kellnr_storage::toolchain_storage::ToolchainStorage;
17use reqwest::Client;
18
19use crate::login_throttle::LoginThrottle;
20use crate::token_cache::TokenCacheManager;
21
22pub type AppState = axum::extract::State<AppStateData>;
23
24// Substates
25pub type DbState = axum::extract::State<Arc<dyn DbProvider>>;
26pub type SettingsState = axum::extract::State<Arc<Settings>>;
27pub type SettingsProvState = axum::extract::State<Arc<SettingsProv>>;
28pub type DocsStorageState = axum::extract::State<Arc<DocsStorage>>;
29pub type CratesIoPrefetchSenderState = axum::extract::State<Sender<CratesioPrefetchMsg>>;
30pub type TokenCacheState = axum::extract::State<Arc<TokenCacheManager>>;
31pub type LoginThrottleState = axum::extract::State<Arc<LoginThrottle>>;
32pub type ToolchainStorageState = axum::extract::State<Option<Arc<ToolchainStorage>>>;
33pub type ProxyClientState = axum::extract::State<Client>;
34pub type BackgroundTasksState = axum::extract::State<BackgroundTasks>;
35pub type IndexFiltersState = axum::extract::State<Arc<IndexFilters>>;
36
37#[derive(Clone, FromRef)]
38pub struct AppStateData {
39    pub db: Arc<dyn DbProvider>,
40    // key that is used for signing cookies
41    pub signing_key: Key,
42    pub settings: Arc<Settings>,
43    /// Per-leaf provenance for the merged `settings`. Only the `/settings`
44    /// web-ui handler reads this; everything else uses the plain `Settings`.
45    pub settings_prov: Arc<SettingsProv>,
46    pub crate_storage: Arc<KellnrCrateStorage>,
47    pub cratesio_storage: Arc<CratesIoCrateStorage>,
48    /// Always present, unlike `toolchain_storage`: `/docs/*` serving and
49    /// manual doc publishing are mounted regardless of `settings.docs.enabled`
50    /// (that flag only gates the automatic generation queue).
51    pub docs_storage: Arc<DocsStorage>,
52    pub cratesio_prefetch_sender: Sender<CratesioPrefetchMsg>,
53    pub token_cache: Arc<TokenCacheManager>,
54    /// Per-username throttle for password authentication attempts.
55    pub login_throttle: Arc<LoginThrottle>,
56    pub toolchain_storage: Option<Arc<ToolchainStorage>>,
57    pub download_counter: Arc<DownloadCounter>,
58    pub proxy_client: Client,
59    pub cratesio_sync: CratesioSync,
60    pub download_filters: Arc<DownloadFilters>,
61    pub index_filters: Arc<IndexFilters>,
62    /// Work that outlives a request, e.g. processing an upload, runs here so
63    /// shutdown waits for it.
64    pub background_tasks: BackgroundTasks,
65}
66
67/// Build a defaults-only `SettingsProv`, every leaf reports
68/// `Category::Default`. Convenient for ad-hoc test `AppStateData`
69/// construction where the `settings_prov` field isn't otherwise relevant.
70#[must_use]
71pub fn default_settings_prov() -> Arc<SettingsProv> {
72    Arc::new(
73        provcfg::Config::new()
74            .build::<SettingsProv>()
75            .expect("default SettingsProv build is infallible"),
76    )
77}