1use std::{collections::BTreeMap, sync::Arc};
2
3use anyhow::Context;
4use askama::Template;
5use axum::{response::IntoResponse, Extension};
6
7use crate::{
8 into_response,
9 methods::{
10 filters,
11 repo::{Refs, Repository, Result},
12 },
13};
14
15#[derive(Template)]
16#[template(path = "repo/refs.html")]
17pub struct View {
18 repo: Repository,
19 refs: Refs,
20 branch: Option<Arc<str>>,
21}
22
23pub async fn handle(
24 Extension(repo): Extension<Repository>,
25 Extension(db): Extension<Arc<rocksdb::DB>>,
26) -> Result<impl IntoResponse> {
27 tokio::task::spawn_blocking(move || {
28 let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
29 .context("Repository does not exist")?;
30
31 let mut heads = BTreeMap::new();
32 for head in repository.get().heads(&db)?.get() {
33 let commit_tree = repository.get().commit_tree(db.clone(), head);
34 let name = head.strip_prefix("refs/heads/");
35
36 if let (Some(name), Some(commit)) = (name, commit_tree.fetch_latest_one()?) {
37 heads.insert(name.to_string(), commit);
38 }
39 }
40
41 let tags = repository.get().tag_tree(db).fetch_all()?;
42
43 Ok(into_response(View {
44 repo,
45 refs: Refs { heads, tags },
46 branch: None,
47 }))
48 })
49 .await
50 .context("Failed to attach to tokio task")?
51}