1use crate::repo_config_loader::RepoConfigLoader;
2use axum::extract::FromRef;
3use meritocrab_core::RepoConfig;
4use meritocrab_github::{GithubApiClient, WebhookSecret};
5use meritocrab_llm::LlmEvaluator;
6use serde::{Deserialize, Serialize};
7use sqlx::{Any, Pool};
8use std::sync::Arc;
9use tokio::sync::Semaphore;
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
13pub struct OAuthConfig {
14 pub client_id: String,
15 pub client_secret: String,
16 pub redirect_url: String,
17}
18
19#[derive(Clone)]
30pub struct AppState {
31 pub db_pool: Pool<Any>,
33
34 pub github_client: Arc<GithubApiClient>,
36
37 pub repo_config: RepoConfig,
39
40 pub webhook_secret: WebhookSecret,
42
43 pub llm_evaluator: Arc<dyn LlmEvaluator>,
45
46 pub llm_semaphore: Arc<Semaphore>,
48
49 pub oauth_config: OAuthConfig,
51
52 pub repo_config_loader: Arc<RepoConfigLoader>,
54}
55
56impl AppState {
57 pub fn new(
59 db_pool: Pool<Any>,
60 github_client: GithubApiClient,
61 repo_config: RepoConfig,
62 webhook_secret: WebhookSecret,
63 llm_evaluator: Arc<dyn LlmEvaluator>,
64 max_concurrent_llm_evals: usize,
65 oauth_config: OAuthConfig,
66 config_cache_ttl_seconds: u64,
67 ) -> Self {
68 let github_client_arc = Arc::new(github_client);
69 let repo_config_loader = Arc::new(RepoConfigLoader::new(
70 github_client_arc.clone(),
71 config_cache_ttl_seconds,
72 ));
73
74 Self {
75 db_pool,
76 github_client: github_client_arc,
77 repo_config,
78 webhook_secret,
79 llm_evaluator,
80 llm_semaphore: Arc::new(Semaphore::new(max_concurrent_llm_evals)),
81 oauth_config,
82 repo_config_loader,
83 }
84 }
85}
86
87impl FromRef<AppState> for WebhookSecret {
89 fn from_ref(state: &AppState) -> Self {
90 state.webhook_secret.clone()
91 }
92}
93
94impl FromRef<AppState> for OAuthConfig {
96 fn from_ref(state: &AppState) -> Self {
97 state.oauth_config.clone()
98 }
99}
100
101impl FromRef<AppState> for Arc<GithubApiClient> {
103 fn from_ref(state: &AppState) -> Self {
104 state.github_client.clone()
105 }
106}