1use std::collections::HashSet;
2
3use chrono::{DateTime, Local};
4use serde::Serialize;
5
6#[derive(Debug, Serialize)]
7pub struct Commit {
8 pub hash: String,
9 pub message: String,
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub commit_type: Option<String>,
12 #[serde(rename = "timestamp")]
13 pub time: DateTime<Local>,
14 pub relative_time: String,
15}
16
17#[derive(Debug, Serialize)]
18pub struct BranchLog {
19 pub name: String,
20 pub commits: Vec<Commit>,
21}
22
23#[derive(Debug, Serialize)]
24pub struct ProjectLog {
25 pub project: String,
26 pub path: String,
27 pub branches: Vec<BranchLog>,
28}
29
30impl BranchLog {
31 pub fn latest_activity(&self) -> Option<&str> {
32 self.commits.first().map(|c| c.relative_time.as_str())
33 }
34}
35
36impl ProjectLog {
37 pub fn total_commits(&self) -> usize {
38 let mut seen = HashSet::new();
39 self.branches
40 .iter()
41 .flat_map(|b| &b.commits)
42 .filter(|c| seen.insert(&c.hash))
43 .count()
44 }
45
46 pub fn latest_activity(&self) -> Option<&str> {
47 self.branches
48 .iter()
49 .flat_map(|b| b.commits.first())
50 .max_by_key(|c| c.time)
51 .map(|c| c.relative_time.as_str())
52 }
53}