use std::collections::HashSet;
use futures::TryFutureExt;
use jacquard_common::types::{did::Did, nsid::Nsid, string::Handle};
use smol_str::SmolStr;
use crate::db::types::DidKey;
use super::*;
#[derive(Serialize, Deserialize)]
pub struct DescribeRepoOutput {
pub did: Did,
pub handle: Handle,
#[serde(serialize_with = "crate::util::did_key_serialize_str")]
#[serde(deserialize_with = "crate::util::did_key_deserialize_str")]
pub signing_key: DidKey<'static>,
pub pds: SmolStr,
pub collections: HashSet<Nsid>,
}
#[derive(Serialize, Deserialize)]
pub struct DescribeRepoRequestData {
pub identifier: AtIdentifier,
}
pub async fn handle(
State(hydrant): State<Hydrant>,
ExtractXrpc(req): ExtractXrpc<DescribeRepoRequestData>,
) -> XrpcResult<Json<DescribeRepoOutput>> {
let did = hydrant
.state
.resolver
.resolve_did(&req.identifier)
.await
.map_err(|e| bad_request(format!("can't resolve identifier: {e}")))?;
let repo = hydrant.repos.get(&did);
// before the doc, so a gone account's identity isn't fetched for nothing
if let Some(reason) = unavailable(&repo).await.map_err(internal_error)? {
return Err(bad_request(reason));
}
let doc = super::resolve_mini_doc::mini_doc_of(&hydrant, &did, &req.identifier).await?;
let collections = repo.collections().map_err(internal_error).await?;
Ok(Json(DescribeRepoOutput {
did: doc.did,
handle: doc.handle,
signing_key: doc.signing_key,
pds: doc.pds,
collections: collections.into_keys().collect(),
}))
}