use std::path::{Path, PathBuf};
use tracing::debug;
use crate::report::errors::Result;
use crate::report::models::ReportData;
pub const AUTHORS_CSV: &str = "authors.csv";
pub const WEEKLY_CSV: &str = "weekly_activity.csv";
pub fn write_author_csv(data: &ReportData, output_dir: &Path) -> Result<PathBuf> {
let path = output_dir.join(AUTHORS_CSV);
let mut w = ::csv::Writer::from_path(&path)?;
w.write_record([
"name",
"email",
"commit_count",
"insertions",
"deletions",
"files_changed",
"first_commit",
"last_commit",
"categories",
])?;
for a in &data.authors {
let categories = serialize_categories(&a.categories);
w.write_record([
a.name.as_str(),
a.email.as_str(),
&a.commit_count.to_string(),
&a.insertions.to_string(),
&a.deletions.to_string(),
&a.files_changed.to_string(),
a.first_commit.as_str(),
a.last_commit.as_str(),
categories.as_str(),
])?;
}
w.flush()?;
debug!(path = %path.display(), rows = data.authors.len(), "wrote authors.csv");
Ok(path)
}
pub fn write_weekly_csv(data: &ReportData, output_dir: &Path) -> Result<PathBuf> {
let path = output_dir.join(WEEKLY_CSV);
let mut w = ::csv::Writer::from_path(&path)?;
w.write_record([
"week",
"author",
"repository",
"commit_count",
"insertions",
"deletions",
"categories",
])?;
for row in &data.weekly_activity {
let categories = serialize_categories(&row.categories);
w.write_record([
row.week.as_str(),
row.author.as_str(),
row.repository.as_str(),
&row.commit_count.to_string(),
&row.insertions.to_string(),
&row.deletions.to_string(),
categories.as_str(),
])?;
}
w.flush()?;
debug!(
path = %path.display(),
rows = data.weekly_activity.len(),
"wrote weekly_activity.csv"
);
Ok(path)
}
fn serialize_categories(map: &std::collections::HashMap<String, usize>) -> String {
let mut entries: Vec<(&String, &usize)> = map.iter().collect();
entries.sort_by(|a, b| a.0.cmp(b.0));
entries
.into_iter()
.map(|(k, v)| format!("{k}={v}"))
.collect::<Vec<_>>()
.join(";")
}