use std::path::{Path, PathBuf};
use crate::repo::Repo;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SourceLocation {
pub revision: GitRevision,
pub path: PathBuf,
pub lines: Option<(usize, usize)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GitRevision {
Head,
Commit(String),
Index,
Worktree,
MergeBase(String, String),
}
impl GitRevision {
pub fn read(&self, repo: &Repo, rel: &Path) -> Option<Vec<u8>> {
match self {
GitRevision::Head => repo.head_bytes(rel),
GitRevision::Commit(sha) => repo.commit_bytes(sha, rel),
GitRevision::Index => repo.index_bytes(rel),
GitRevision::Worktree => std::fs::read(repo.workdir.join(rel)).ok(),
GitRevision::MergeBase(a, b) => {
let base = repo.merge_base(a, b)?;
repo.commit_bytes(&base, rel)
}
}
}
}
impl SourceLocation {
pub fn revision_slug(&self) -> String {
match &self.revision {
GitRevision::Head => "HEAD".into(),
GitRevision::Commit(sha) => sha.clone(),
GitRevision::Index => "index".into(),
GitRevision::Worktree => "worktree".into(),
GitRevision::MergeBase(a, b) => format!("{a}...{b}"),
}
}
}