rpo 0.1.0-beta.4

Git contribution analysis: commits, file changes, and per-line authorship over time as polars DataFrames
//! Polars frame construction. This is the only module that depends on polars.

use std::path::Path;

use crate::backend::ChangeKind;

pub mod blame;
pub mod commits;
pub mod file_changes; // stub file created here, implemented in Task 12

#[derive(Clone, Debug)]
pub struct CommitRecord {
    pub sha: String,
    pub short_sha: String,
    pub author_name: String,
    pub author_email: String,
    pub canonical_author_name: String,
    pub canonical_author_email: String,
    pub committer_name: String,
    pub committer_email: String,
    pub canonical_committer_name: String,
    pub canonical_committer_email: String,
    pub author_time_ms: i64,
    pub commit_time_ms: i64,
    pub parent_count: u32,
    pub is_merge: bool,
    pub message_subject: String,
    pub files_changed: u32,
    pub insertions: u64,
    pub deletions: u64,
}

#[derive(Clone, Debug)]
pub struct FileChangeRecord {
    pub sha: String,
    pub commit_time_ms: i64,
    pub canonical_author_name: String,
    pub canonical_author_email: String,
    pub canonical_committer_name: String,
    pub canonical_committer_email: String,
    pub path: String,
    pub old_path: Option<String>,
    pub change_kind: ChangeKind,
    pub insertions: u64,
    pub deletions: u64,
    pub extension: Option<String>,
    pub is_generated: bool,
    pub is_vendored: bool,
}

#[derive(Clone, Debug)]
pub struct BlameRecord {
    pub snapshot_sha: String,
    pub snapshot_time_ms: i64,
    pub snapshot_label: Option<String>,
    pub path: String,
    pub start_line: u32,
    pub line_count: u32,
    pub commit_sha: String,
    pub canonical_author_name: String,
    pub canonical_author_email: String,
    pub canonical_committer_name: String,
    pub canonical_committer_email: String,
    pub commit_time_ms: i64,
    pub extension: Option<String>,
}

pub fn extension_of(path: &Path) -> Option<String> {
    path.extension()
        .and_then(|os| os.to_str())
        .map(|s| s.to_lowercase())
}

pub fn change_kind_str(k: ChangeKind) -> &'static str {
    match k {
        ChangeKind::Added => "added",
        ChangeKind::Modified => "modified",
        ChangeKind::Deleted => "deleted",
        ChangeKind::Renamed => "renamed",
        ChangeKind::Copied => "copied",
        ChangeKind::TypeChange => "typechange",
    }
}