diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-08-01 13:26:44 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-08-01 13:26:44 +0200 |
commit | 1b359d5f6fa63352c79462d5eeab40d4e2f10d89 (patch) | |
tree | a3e05192a2604b714d02ee143dac4205986f9489 /src | |
parent | 54306d2e9a29fb75432cb01e627494e2eeef723c (diff) |
Add route impl for tree
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/routes/tree.rs | 87 |
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) + } + } +} |