diff options
author | Tuomas Siipola | 2020-01-03 16:48:25 +0200 |
---|---|---|
committer | Tuomas Siipola | 2020-01-03 16:48:25 +0200 |
commit | 3cbd74ad6161112fbd41723b48dcfa66e9caa603 (patch) | |
tree | a8435a2e7171fc4b9ba69a182ba7b13c06841a07 /src | |
parent | 0b66d9a4291aa7ca5bb779eba192e89329a9e774 (diff) |
Add commit page
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 73 |
1 files changed, 70 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs index fc8df9d..23c5a6f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,6 +73,29 @@ async fn index() -> Result<Response<Body>, Infallible> { enum Tab { Summary, Tree, + Commit, +} + +struct Commit<'a> { + id: String, + commit: git2::Commit<'a>, +} + +impl<'a> Commit<'a> { + fn new(commit: git2::Commit<'a>) -> Self { + Self { + id: format!("{}", commit.id()), + commit, + } + } + + fn summary(&self) -> Option<&str> { + self.commit.summary() + } + + fn author(&self) -> git2::Signature { + self.commit.author() + } } #[derive(Template)] @@ -81,7 +104,7 @@ struct SummaryTemplate<'a> { tab: Tab, repo: &'a Repo, readme: Option<&'a str>, - commits: &'a [git2::Commit<'a>], + commits: &'a [Commit<'a>], } fn render_markdown(input: &str) -> String { @@ -109,13 +132,13 @@ async fn repo(name: &str) -> Result<Response<Body>, Infallible> { revwalk.push_head().unwrap(); let commits: Vec<_> = revwalk .take(3) - .map(|id| repo.find_commit(id.unwrap()).unwrap()) + .map(|id| Commit::new(repo.find_commit(id.unwrap()).unwrap())) .collect(); let tmpl = SummaryTemplate { tab: Tab::Summary, repo: &read_repo(name).unwrap(), readme: readme.as_deref(), - commits: &commits, + commits: commits.as_slice(), }; Ok(Response::builder() .header("Content-Type", "text/html") @@ -283,6 +306,49 @@ async fn blob(name: &str, parts: &[&str]) -> Result<Response<Body>, Infallible> .unwrap()) } +#[derive(Template)] +#[template(path = "commit.html")] +struct CommitTemplate<'a> { + tab: Tab, + repo: &'a Repo, + commit: git2::Commit<'a>, + diff: &'a [(char, String)], +} + +async fn commit(name: &str, id: &str) -> Result<Response<Body>, Infallible> { + let repo = Repository::open(Path::new("..").join(name)).unwrap(); + let commit = repo.find_commit(git2::Oid::from_str(id).unwrap()).unwrap(); + let parent = commit.parent(0).unwrap(); + + let mut diff_output = Vec::new(); + let diff = repo + .diff_tree_to_tree( + Some(&parent.tree().unwrap()), + Some(&commit.tree().unwrap()), + None, + ) + .unwrap(); + diff.print(git2::DiffFormat::Patch, |_delta, _hunk, line| { + diff_output.push(( + line.origin(), + String::from_utf8_lossy(line.content()).to_string(), + )); + true + }) + .unwrap(); + + let tmpl = CommitTemplate { + tab: Tab::Commit, + repo: &read_repo(name).unwrap(), + commit, + diff: &diff_output, + }; + Ok(Response::builder() + .header("Content-Type", "text/html") + .body(Body::from(tmpl.render().unwrap())) + .unwrap()) +} + async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> { if req.method() != Method::GET { return Ok(Response::builder() @@ -323,6 +389,7 @@ async fn router(req: Request<Body>) -> Result<Response<Body>, Infallible> { )) .unwrap()), [name] => repo(name).await, + [name, "commit", id] => commit(name, id).await, _ => Ok(Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("not found")) |