Files
mdrs-client-rust/src/api/users.rs
T
orrisroot 769a5a68e2 refactor: unify error handling with anyhow and add From conversions
Phase 5: Replace all Box<dyn Error> return types with anyhow::Result<T>
throughout the codebase. Replace string-based Err("msg".into()) and
format!().into() patterns with bail!() and anyhow!() macros. Fix
dirs::home_dir().unwrap() in settings.rs to use a fallback path instead
of panicking when HOME is unset. Remove stray use std::error::Error
imports no longer needed.

Phase 6: Add From<&User> for CacheUser in models/user.rs and
From<&Laboratory>/From<&Laboratories> for CacheLaboratory/CacheLabsWrapper
in models/laboratory.rs. Simplify commands/login.rs to use .into()
conversions, removing the redundant to_cache_user() and to_cache_labs()
helper functions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 14:19:10 +09:00

59 lines
1.7 KiB
Rust

use crate::connection::MDRSConnection;
use crate::models::user::User as ModelUser;
use serde::Deserialize;
use anyhow::{bail};
/// Full API response shape from GET v3/users/current/
#[derive(Debug, Deserialize)]
struct UsersApiCurrentResponse {
id: u32,
username: String,
laboratories: Vec<UsersCurrentResponseLaboratory>,
is_reviewer: bool,
}
#[derive(Debug, Deserialize)]
struct UsersCurrentResponseLaboratory {
id: u32,
}
#[derive(Deserialize)]
struct TokenRefreshResponse {
access: String,
}
impl MDRSConnection {
/// Fetch current user and return the slim 4-field model matching the Python cache format.
pub async fn get_current_user(&self) -> Result<ModelUser, reqwest::Error> {
let resp = self.get("v3/users/current/").await?;
let obj = resp.json::<UsersApiCurrentResponse>().await?;
let laboratory_ids = obj.laboratories.into_iter().map(|l| l.id).collect();
Ok(ModelUser {
id: obj.id,
username: obj.username,
laboratory_ids,
is_reviewer: obj.is_reviewer,
})
}
/// Refresh the access token using the refresh token.
/// POST v3/users/token/refresh/ {refresh: ...} -> {access: new_access}
pub async fn token_refresh(
&self,
refresh_token: &str,
) -> Result<String, anyhow::Error> {
let body = serde_json::json!({ "refresh": refresh_token });
let resp = self
.client
.post(self.build_url("v3/users/token/refresh/"))
.json(&body)
.send()
.await?;
if !resp.status().is_success() {
bail!("Token refresh failed: {}", resp.status());
}
let r: TokenRefreshResponse = resp.json().await?;
Ok(r.access)
}
}