summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-08-01 13:26:44 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-08-01 13:26:44 +0200
commit1b359d5f6fa63352c79462d5eeab40d4e2f10d89 (patch)
treea3e05192a2604b714d02ee143dac4205986f9489 /src
parent54306d2e9a29fb75432cb01e627494e2eeef723c (diff)
Add route impl for tree
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r--src/routes/tree.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/routes/tree.rs b/src/routes/tree.rs
new file mode 100644
index 0000000..aa590d5
--- /dev/null
+++ b/src/routes/tree.rs
@@ -0,0 +1,87 @@
+use std::sync::Arc;
+
+use actix_web::HttpResponse;
+use actix_web::web;
+
+use crate::repository::get_repository_stat;
+use crate::routes::error::RepositoryError;
+
+pub async fn tree<'a>(web::Path((repo_name, branch_name, tree_path)): web::Path<(String, String, String)>, data: web::Data<Arc<crate::state::AppState<'a>>>) -> Result<HttpResponse, RepositoryError> {
+ let repo_state = data.repos()
+ .get(&repo_name)
+ .ok_or_else(|| RepositoryError::RepoNotFound)?;
+
+ let repo_stat = get_repository_stat(&repo_name, repo_state.clone())
+ .await
+ .map_err(|e| RepositoryError::Str(e.to_string()))?;
+
+ let tree_path = tree_path.split("/").collect::<Vec<_>>();
+ let repo_lock = repo_state.lock()
+ .map_err(|_| RepositoryError::Str("Lock error".to_string()))?;
+
+ let root = repo_lock.repo()
+ .find_branch(&branch_name, git2::BranchType::Local)
+ .map_err(|_| crate::routes::error::RepositoryError::Str("Branch not found".to_string()))?
+ .get()
+ .peel_to_tree()
+ .map_err(|e| crate::routes::error::RepositoryError::Str(e.to_string()))?;
+
+ let tree_object = crate::tree::load_tree_at(repo_lock.repo(), &root, &tree_path)
+ .map_err(|e| RepositoryError::Str(e.to_string()))?;
+
+ let tree_object = match tree_object {
+ None => {
+ return Ok(HttpResponse::NotFound().finish())
+ }
+
+ Some(to) => to,
+ };
+
+ match tree_object.content {
+ crate::tree::TreeObjectContent::File { size, content, is_binary } => {
+ let content = crate::highlight::highlight(&content, data.theme())
+ .map_err(|e| RepositoryError::Str(e.to_string()))?;
+ let content = content.value
+ .lines()
+ .map(String::from)
+ .enumerate()
+ .map(crate::templates::blob::Line::from)
+ .collect();
+
+ crate::templates::blob::render(data.handlebars(), crate::templates::blob::Data {
+ name: &repo_name,
+ branch_names: &repo_stat.branches,
+ tag_names: &repo_stat.tags,
+ branch_name: &branch_name,
+
+ size,
+ content,
+ is_binary,
+ })
+ .map(|body| HttpResponse::Ok().body(body))
+ .map_err(RepositoryError::from)
+ },
+
+ crate::tree::TreeObjectContent::Dir { content } => {
+ let content = content.into_iter()
+ .map(|tree_object_meta| {
+ crate::templates::tree::TreeElement {
+ is_dir: tree_object_meta.is_dir,
+ name: tree_object_meta.name,
+ }
+ })
+ .collect();
+
+ crate::templates::tree::render(data.handlebars(), crate::templates::tree::Data {
+ name: &repo_name,
+ branch_names: &repo_stat.branches,
+ tag_names: &repo_stat.tags,
+ branch_name: &branch_name,
+
+ content,
+ })
+ .map(|body| HttpResponse::Ok().body(body))
+ .map_err(RepositoryError::from)
+ }
+ }
+}