gitscope
← rgit / 0.1.0 / src/methods/repo/tree.rs
https://dev.kronoz.win/r/rgit.git
src/methods/repo/tree.rs · Rust
Blame Raw
 1use std::{
 2    fmt::{Display, Formatter},
 3    sync::Arc,
 4};
 5
 6use askama::Template;
 7use axum::{extract::Query, response::Response, Extension};
 8use serde::Deserialize;
 9
10use crate::{
11    git::{FileWithContent, PathDestination, TreeItem},
12    into_response,
13    methods::{
14        filters,
15        repo::{ChildPath, Repository, RepositoryPath, Result},
16    },
17    Git,
18};
19
20#[derive(Deserialize)]
21pub struct UriQuery {
22    id: Option<String>,
23    #[serde(rename = "h")]
24    branch: Option<String>,
25}
26
27impl Display for UriQuery {
28    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29        let mut prefix = "?";
30
31        if let Some(id) = self.id.as_deref() {
32            write!(f, "{prefix}id={id}")?;
33            prefix = "&";
34        }
35
36        if let Some(branch) = self.branch.as_deref() {
37            write!(f, "{prefix}h={branch}")?;
38        }
39
40        Ok(())
41    }
42}
43
44#[derive(Template)]
45#[template(path = "repo/tree.html")]
46#[allow(clippy::module_name_repetitions)]
47pub struct TreeView {
48    pub repo: Repository,
49    pub items: Vec<TreeItem>,
50    pub query: UriQuery,
51}
52
53#[derive(Template)]
54#[template(path = "repo/file.html")]
55pub struct FileView {
56    pub repo: Repository,
57    pub file: FileWithContent,
58}
59
60pub async fn handle(
61    Extension(repo): Extension<Repository>,
62    Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
63    Extension(ChildPath(child_path)): Extension<ChildPath>,
64    Extension(git): Extension<Arc<Git>>,
65    Query(query): Query<UriQuery>,
66) -> Result<Response> {
67    let open_repo = git.repo(repository_path).await?;
68
69    Ok(
70        match open_repo
71            .path(child_path, query.id.as_deref(), query.branch.clone())
72            .await?
73        {
74            PathDestination::Tree(items) => into_response(&TreeView { repo, items, query }),
75            PathDestination::File(file) => into_response(&FileView { repo, file }),
76        },
77    )
78}