this repo has no description
1use crate::state::AppState;
2use axum::{
3 Json,
4 extract::{Query, State},
5 http::StatusCode,
6 response::{IntoResponse, Response},
7};
8use serde::Deserialize;
9use serde_json::json;
10
11#[derive(Deserialize)]
12pub struct DescribeRepoInput {
13 pub repo: String,
14}
15
16pub async fn describe_repo(
17 State(state): State<AppState>,
18 Query(input): Query<DescribeRepoInput>,
19) -> Response {
20 let user_row = if input.repo.starts_with("did:") {
21 sqlx::query!(
22 "SELECT id, handle, did FROM users WHERE did = $1",
23 input.repo
24 )
25 .fetch_optional(&state.db)
26 .await
27 .map(|opt| opt.map(|r| (r.id, r.handle, r.did)))
28 } else {
29 sqlx::query!(
30 "SELECT id, handle, did FROM users WHERE handle = $1",
31 input.repo
32 )
33 .fetch_optional(&state.db)
34 .await
35 .map(|opt| opt.map(|r| (r.id, r.handle, r.did)))
36 };
37 let (user_id, handle, did) = match user_row {
38 Ok(Some((id, handle, did))) => (id, handle, did),
39 Ok(None) => {
40 return (
41 StatusCode::NOT_FOUND,
42 Json(json!({"error": "RepoNotFound", "message": "Repo not found"})),
43 )
44 .into_response();
45 }
46 Err(_) => {
47 return (
48 StatusCode::INTERNAL_SERVER_ERROR,
49 Json(json!({"error": "InternalError"})),
50 )
51 .into_response();
52 }
53 };
54 let collections_query = sqlx::query!(
55 "SELECT DISTINCT collection FROM records WHERE repo_id = $1",
56 user_id
57 )
58 .fetch_all(&state.db)
59 .await;
60 let collections: Vec<String> = match collections_query {
61 Ok(rows) => rows.iter().map(|r| r.collection.clone()).collect(),
62 Err(_) => Vec::new(),
63 };
64 let did_doc = json!({
65 "id": did,
66 "alsoKnownAs": [format!("at://{}", handle)]
67 });
68 Json(json!({
69 "handle": handle,
70 "did": did,
71 "didDoc": did_doc,
72 "collections": collections,
73 "handleIsCorrect": true
74 }))
75 .into_response()
76}