use jacquard_common::types::{string::Did, tid::Tid};
use crate::ingest::stream::AccountStatus;
use crate::types::RepoStatus;
use super::*;
#[derive(Deserialize)]
pub struct GetRepoStatus {
pub did: Did,
}
#[derive(Serialize)]
pub struct GetRepoStatusOutput {
pub active: bool,
pub did: Did,
#[serde(skip_serializing_if = "Option::is_none")]
pub rev: Option<Tid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<AccountStatus<'static>>,
}
pub async fn handle(
State(hydrant): State<Hydrant>,
ExtractXrpc(req): ExtractXrpc<GetRepoStatus>,
) -> XrpcResult<Json<GetRepoStatusOutput>> {
let Some(state) = hydrant
.repos
.get(&req.did)
.state()
.await
.map_err(internal_error)?
else {
return Err(xrpc_error(StatusCode::NOT_FOUND, "RepoNotFound", None));
};
let status = repo_status_to_api(state.status);
// rev is only meaningful when the repo is active and has been synced at least once
let rev = state
.active
.then(|| state.root.map(|c| c.rev.to_tid()))
.flatten();
Ok(Json(GetRepoStatusOutput {
active: state.active,
did: req.did,
rev,
status,
}))
}
pub(super) fn repo_status_to_api(status: RepoStatus) -> Option<AccountStatus<'static>> {
match status {
RepoStatus::Synced => None,
RepoStatus::Deactivated => Some(AccountStatus::Deactivated),
RepoStatus::Takendown => Some(AccountStatus::Takendown),
RepoStatus::Suspended => Some(AccountStatus::Suspended),
RepoStatus::Deleted => Some(AccountStatus::Deleted),
// per spec, desynchronized and throttled have active=may-be-true
RepoStatus::Desynchronized => Some(AccountStatus::Desynchronized),
RepoStatus::Throttled => Some(AccountStatus::Throttled),
RepoStatus::Error(_) => Some(AccountStatus::Desynchronized),
}
}