gitscope
← rgit / main / src/methods/repo/refs.rs
https://dev.kronoz.win/r/rgit.git
src/methods/repo/refs.rs · Rust
Blame Raw
 1use std::{collections::BTreeMap, sync::Arc};
 2
 3use crate::{
 4    into_response,
 5    methods::{
 6        filters,
 7        repo::{Refs, Repository, Result},
 8    },
 9};
10use anyhow::Context;
11use askama::Template;
12use axum::{Extension, response::IntoResponse};
13use rkyv::string::ArchivedString;
14use yoke::Yoke;
15
16#[derive(Template)]
17#[template(path = "repo/refs.html")]
18pub struct View {
19    repo: Repository,
20    refs: Refs,
21    branch: Option<Arc<str>>,
22}
23
24pub async fn handle(
25    Extension(repo): Extension<Repository>,
26    Extension(db): Extension<Arc<rocksdb::DB>>,
27) -> Result<impl IntoResponse> {
28    tokio::task::spawn_blocking(move || {
29        let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
30            .context("Repository does not exist")?;
31        let repository = repository.get();
32
33        let heads_db = repository.heads(&db)?;
34        let heads_db = heads_db.as_ref().map(Yoke::get);
35
36        let mut heads = BTreeMap::new();
37        if let Some(archived_heads) = heads_db {
38            for head in archived_heads
39                .0
40                .as_slice()
41                .iter()
42                .map(ArchivedString::as_str)
43            {
44                let commit_tree = repository.commit_tree(db.clone(), head);
45                let name = head.strip_prefix("refs/heads/");
46
47                if let (Some(name), Some(commit)) = (name, commit_tree.fetch_latest_one()?) {
48                    heads.insert(name.to_string(), commit);
49                }
50            }
51        }
52
53        let tags = repository.tag_tree(db).fetch_all()?;
54
55        Ok(into_response(View {
56            repo,
57            refs: Refs { heads, tags },
58            branch: None,
59        }))
60    })
61    .await
62    .context("Failed to attach to tokio task")?
63}