aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTuomas Siipola2020-01-03 16:48:25 +0200
committerTuomas Siipola2020-01-03 16:48:25 +0200
commit3cbd74ad6161112fbd41723b48dcfa66e9caa603 (patch)
treea8435a2e7171fc4b9ba69a182ba7b13c06841a07 /src
parent0b66d9a4291aa7ca5bb779eba192e89329a9e774 (diff)
Add commit page
Diffstat (limited to 'src')
-rw-r--r--src/main.rs73
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"))