From e37a2d9263c91d80906686ac45030550f26b17f3 Mon Sep 17 00:00:00 2001 From: Jonas Rabenstein Date: Thu, 13 Aug 2026 13:39:36 +0200 Subject: [PATCH] cargo fmt --- src/config.rs | 26 +++++----------- src/db.rs | 1 - src/intervals.rs | 77 ++++++++++------------------------------------ src/leaderboard.rs | 12 ++++++-- src/main.rs | 62 ++++++++++++------------------------- src/web.rs | 2 +- 6 files changed, 54 insertions(+), 126 deletions(-) diff --git a/src/config.rs b/src/config.rs index 40ced39..5a832df 100644 --- a/src/config.rs +++ b/src/config.rs @@ -54,9 +54,7 @@ impl IntervalsRateLimiters { .expect("Intervals IP limiter mutex poisoned"); let next = match *last { - Some(previous) => { - std::cmp::max(now, previous + IP_REQUEST_INTERVAL) - } + Some(previous) => std::cmp::max(now, previous + IP_REQUEST_INTERVAL), None => now, }; @@ -183,15 +181,13 @@ impl Config { cookie_secure, - intervals_rate_limiters: - IntervalsRateLimiters::default(), + intervals_rate_limiters: IntervalsRateLimiters::default(), }) } } fn required(name: &str) -> Result { - let value = env::var(name) - .with_context(|| format!("{name} is not configured"))?; + let value = env::var(name).with_context(|| format!("{name} is not configured"))?; if value.trim().is_empty() { anyhow::bail!("{name} is empty"); @@ -201,9 +197,7 @@ fn required(name: &str) -> Result { } fn optional(name: &str) -> Option { - env::var(name) - .ok() - .filter(|value| !value.trim().is_empty()) + env::var(name).ok().filter(|value| !value.trim().is_empty()) } #[cfg(test)] @@ -221,9 +215,7 @@ mod tests { limiters.wait_for_ip_slot().await; } - assert!( - Instant::now().duration_since(start) >= Duration::from_millis(190) - ); + assert!(Instant::now().duration_since(start) >= Duration::from_millis(190)); } #[tokio::test] @@ -234,14 +226,10 @@ mod tests { let start = Instant::now(); limiters.wait_for_caller("caller-a").await; - assert!( - Instant::now().duration_since(start) >= Duration::from_millis(70) - ); + assert!(Instant::now().duration_since(start) >= Duration::from_millis(70)); let start = Instant::now(); limiters.wait_for_caller("caller-b").await; - assert!( - Instant::now().duration_since(start) < Duration::from_millis(40) - ); + assert!(Instant::now().duration_since(start) < Duration::from_millis(40)); } } diff --git a/src/db.rs b/src/db.rs index 51ef3e6..394237f 100644 --- a/src/db.rs +++ b/src/db.rs @@ -232,7 +232,6 @@ pub async fn upsert_oauth_athlete( Ok(row.try_get("id")?) } - /// Ensure that an athlete accessible through the current session exists /// locally so activities can reference it. The session credential itself is /// intentionally not stored here; callers continue to use their authenticated diff --git a/src/intervals.rs b/src/intervals.rs index 581ce8e..612b527 100644 --- a/src/intervals.rs +++ b/src/intervals.rs @@ -20,10 +20,7 @@ pub struct IntervalsClient { impl IntervalsClient { pub fn new(config: Config) -> Self { - let authentication = config - .intervals_api_key - .clone() - .map(Authentication::ApiKey); + let authentication = config.intervals_api_key.clone().map(Authentication::ApiKey); Self { client: Client::new(), @@ -43,10 +40,7 @@ impl IntervalsClient { /// Create a client using an OAuth access token. /// Requests are authenticated with HTTP Bearer auth. - pub fn with_access_token( - config: Config, - access_token: impl Into, - ) -> Self { + pub fn with_access_token(config: Config, access_token: impl Into) -> Self { Self { client: Client::new(), config, @@ -70,9 +64,7 @@ impl IntervalsClient { .intervals_client_id .clone() .unwrap_or_else(|| token.clone())), - None => Err(anyhow!( - "Intervals.icu authentication is not configured" - )), + None => Err(anyhow!("Intervals.icu authentication is not configured")), } } @@ -84,29 +76,17 @@ impl IntervalsClient { ) } - fn authenticated( - &self, - request: reqwest::RequestBuilder, - ) -> Result { + fn authenticated(&self, request: reqwest::RequestBuilder) -> Result { match self.authentication.as_ref() { - Some(Authentication::ApiKey(token)) => { - Ok(request.basic_auth("API_KEY", Some(token))) - } - Some(Authentication::Bearer(token)) => { - Ok(request.bearer_auth(token)) - } - None => Err(anyhow!( - "Intervals.icu authentication is not configured" - )), + Some(Authentication::ApiKey(token)) => Ok(request.basic_auth("API_KEY", Some(token))), + Some(Authentication::Bearer(token)) => Ok(request.bearer_auth(token)), + None => Err(anyhow!("Intervals.icu authentication is not configured")), } } async fn get_json(&self, url: String) -> Result { let caller = self.rate_limit_caller()?; - let limiters = self - .config - .intervals_rate_limiters - .clone(); + let limiters = self.config.intervals_rate_limiters.clone(); // Intervals.icu enforces an additional limit of ten calls/sec per // source IP. Pace every request start globally for this process. @@ -126,10 +106,8 @@ impl IntervalsClient { .context("Intervals.icu request failed")?; let status = response.status(); - let retry_after = - parse_retry_after(response.headers().get("Retry-After")); - let rate_limit = - parse_rate_limit_headers(response.headers()); + let retry_after = parse_retry_after(response.headers().get("Retry-After")); + let rate_limit = parse_rate_limit_headers(response.headers()); if status == reqwest::StatusCode::TOO_MANY_REQUESTS { let body = response @@ -173,11 +151,7 @@ impl IntervalsClient { .context("cannot read Intervals.icu response")?; if !status.is_success() { - return Err(anyhow!( - "Intervals.icu returned HTTP {}: {}", - status, - body - )); + return Err(anyhow!("Intervals.icu returned HTTP {}: {}", status, body)); } tracing::debug!( @@ -190,12 +164,7 @@ impl IntervalsClient { ); return serde_json::from_str(&body) - .with_context(|| { - format!( - "invalid JSON returned by Intervals.icu: {}", - body - ) - }); + .with_context(|| format!("invalid JSON returned by Intervals.icu: {}", body)); } unreachable!("rate-limit retry loop must return") @@ -519,10 +488,7 @@ impl IntervalsClient { } } - -fn parse_retry_after( - value: Option<&reqwest::header::HeaderValue>, -) -> Option { +fn parse_retry_after(value: Option<&reqwest::header::HeaderValue>) -> Option { let value = value?.to_str().ok()?.trim(); let seconds = value.parse::().ok()?; Some(std::time::Duration::from_secs(seconds)) @@ -537,9 +503,7 @@ fn parse_retry_after( fn parse_rate_limit_headers( headers: &reqwest::header::HeaderMap, ) -> (Option, Option, Option, Option) { - fn pair( - value: Option<&reqwest::header::HeaderValue>, - ) -> (Option, Option) { + fn pair(value: Option<&reqwest::header::HeaderValue>) -> (Option, Option) { let Some(value) = value else { return (None, None); }; @@ -556,17 +520,10 @@ fn parse_rate_limit_headers( (first, second) } - let (limit_15m, limit_daily) = - pair(headers.get("X-RateLimit-Limit")); - let (remaining_15m, remaining_daily) = - pair(headers.get("X-RateLimit-Remaining")); + let (limit_15m, limit_daily) = pair(headers.get("X-RateLimit-Limit")); + let (remaining_15m, remaining_daily) = pair(headers.get("X-RateLimit-Remaining")); - ( - limit_15m, - limit_daily, - remaining_15m, - remaining_daily, - ) + (limit_15m, limit_daily, remaining_15m, remaining_daily) } fn parse_datetime(value: &str) -> Result> { diff --git a/src/leaderboard.rs b/src/leaderboard.rs index bbf0af3..2d459a0 100644 --- a/src/leaderboard.rs +++ b/src/leaderboard.rs @@ -36,7 +36,10 @@ pub async fn api( build(&state.db, query.group_id, offset, limit) .await .map(|groups| { - let returned = groups.iter().map(|group| group.rows.len() as i64).sum::(); + let returned = groups + .iter() + .map(|group| group.rows.len() as i64) + .sum::(); Json(LeaderboardPage { groups, next_offset: offset + returned, @@ -52,7 +55,12 @@ pub async fn api( }) } -pub async fn build(db: &PgPool, group_id: Option, offset: i64, limit: i64) -> Result> { +pub async fn build( + db: &PgPool, + group_id: Option, + offset: i64, + limit: i64, +) -> Result> { let rows = sqlx::query( r#" WITH bucketed AS ( diff --git a/src/main.rs b/src/main.rs index d7935da..c2e0234 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,15 +162,11 @@ async fn sync_index( jar: axum_extra::extract::cookie::CookieJar, ) -> Result, (axum::http::StatusCode, String)> { let session = current_session_athlete(&state, &jar) - .await - .map_err(http_error)?; - - let client = - IntervalsClient::with_api_key(state.config.clone(), session.access_token.clone()); - let athletes = client - .athletes() .await .map_err(http_error)?; + + let client = IntervalsClient::with_api_key(state.config.clone(), session.access_token.clone()); + let athletes = client.athletes().await.map_err(http_error)?; let athletes = athletes .as_array() .ok_or_else(|| http_error(anyhow!("athletes response is not an array")))?; @@ -310,13 +306,9 @@ async fn sync_athlete( */ let client = IntervalsClient::with_api_key(state.config.clone(), session.access_token.clone()); - let target_display_name = ensure_accessible_athlete( - &state, - &client, - &athlete_id, - ) - .await - .map_err(http_error)?; + let target_display_name = ensure_accessible_athlete(&state, &client, &athlete_id) + .await + .map_err(http_error)?; let target_athlete_id = local_athlete(&state.db, &athlete_id) .await @@ -770,13 +762,9 @@ async fn sync_import_activity( let client = IntervalsClient::with_api_key(state.config.clone(), session.access_token.clone()); - ensure_accessible_athlete( - &state, - &client, - &athlete_id, - ) - .await - .map_err(http_error)?; + ensure_accessible_athlete(&state, &client, &athlete_id) + .await + .map_err(http_error)?; match process_activity_with_client( state.clone(), @@ -876,13 +864,9 @@ async fn sync_import_visible( let client = IntervalsClient::with_api_key(state.config.clone(), session.access_token.clone()); - ensure_accessible_athlete( - &state, - &client, - &athlete_id, - ) - .await - .map_err(http_error)?; + ensure_accessible_athlete(&state, &client, &athlete_id) + .await + .map_err(http_error)?; let target_athlete_id = local_athlete(&state.db, &athlete_id) .await @@ -975,15 +959,12 @@ async fn ensure_accessible_athlete( client: &IntervalsClient, athlete_id: &str, ) -> Result { - let athlete = client - .athlete(athlete_id) - .await - .with_context(|| { - format!( - "cannot access Intervals.icu athlete {} with current authentication token", - athlete_id - ) - })?; + let athlete = client.athlete(athlete_id).await.with_context(|| { + format!( + "cannot access Intervals.icu athlete {} with current authentication token", + athlete_id + ) + })?; let display_name = athlete .get("name") @@ -992,12 +973,7 @@ async fn ensure_accessible_athlete( .unwrap_or(athlete_id) .to_string(); - db::ensure_local_athlete( - &state.db, - athlete_id, - &display_name, - ) - .await?; + db::ensure_local_athlete(&state.db, athlete_id, &display_name).await?; Ok(display_name) } diff --git a/src/web.rs b/src/web.rs index 9feb35a..616cd4e 100644 --- a/src/web.rs +++ b/src/web.rs @@ -728,7 +728,7 @@ function initLeaderboardElements(root){ const leaderboardList=document.getElementById('leaderboard-list'); if(leaderboardList){ const status=document.getElementById('leaderboard-status'),sentinel=document.getElementById('leaderboard-sentinel'),groups=new Map(); - let offset=0,loading=false,hasMore=true; const pageSize=50; + let offset=0,loading=false,hasMore=true; const pageSize=25; async function loadLeaderboard(){ if(loading||!hasMore)return; loading=true; try{