Skip to main content

sley_ref_filter/
context.rs

1//! Per-ref rendering context shared by the for-each-ref format renderer.
2
3use super::contents::{ForEachRefContents, ForEachRefPeeledObject};
4use super::tracking::{ForEachRefPush, ForEachRefUpstream};
5use super::{ForEachRefQuoteMode, ForEachRefTrack, shorten_unambiguous_ref};
6use sley_core::{ObjectFormat, ObjectId};
7use sley_odb::FileObjectDatabase;
8use sley_object::ObjectType;
9use std::collections::HashSet;
10use std::path::Path;
11
12/// The signature facts the `%(signature[:opt])` atom family renders, mirroring
13/// git's `grab_signature` field access. The concrete verifier stays a CLI
14/// adapter (GPG/SSH subprocess plumbing); this trait is the sink boundary.
15pub trait ForEachRefSignatureVerification {
16    /// gpg's human-readable verification output (the bare `%(signature)` atom).
17    fn bare_output(&self) -> &[u8];
18    /// 'G'/'U'/'B'/'E'/'N' — git downgrades good-but-untrusted to 'U'.
19    fn grade_byte(&self) -> u8;
20    fn key(&self) -> &str;
21    fn signer(&self) -> &str;
22    fn fingerprint(&self) -> &str;
23    fn primary_fingerprint(&self) -> &str;
24    fn trust(&self) -> &str;
25}
26
27/// Identity rewriting for the `mailmap` atom options. The mailmap parser
28/// remains a CLI adapter; ref-filter only needs the rewrite.
29pub trait ForEachRefMailmapRewrite {
30    fn rewrite_identity(&self, identity: &[u8]) -> (Vec<u8>, Vec<u8>);
31}
32
33pub struct ForEachRefFormatContext<'a> {
34    pub git_dir: &'a Path,
35    pub db: &'a FileObjectDatabase,
36    pub format: ObjectFormat,
37    pub refname: &'a str,
38    pub oid: &'a ObjectId,
39    pub deltabase: &'a ObjectId,
40    pub object_type: ObjectType,
41    pub object_body: &'a [u8],
42    pub object_size: usize,
43    pub object_disk_size: Option<u64>,
44    pub color: bool,
45    pub quote: ForEachRefQuoteMode,
46    pub objectname_abbrev: Option<usize>,
47    pub objectname_candidates: &'a [ObjectId],
48    pub worktree_path: Option<&'a str>,
49    pub is_head: bool,
50    pub symref: Option<&'a str>,
51    pub upstream: Option<ForEachRefUpstream>,
52    pub push: Option<ForEachRefPush>,
53    pub upstream_track: Option<ForEachRefTrack>,
54    pub push_track: Option<ForEachRefTrack>,
55    pub contents: Option<ForEachRefContents<'a>>,
56    pub peeled_object: Option<ForEachRefPeeledObject<'a>>,
57    // %(signature*) verification of the ref object and its peeled tag target.
58    pub signature: Option<&'a dyn ForEachRefSignatureVerification>,
59    pub peeled_signature: Option<&'a dyn ForEachRefSignatureVerification>,
60    pub mailmap: &'a dyn ForEachRefMailmapRewrite,
61    // All ref names in the store + `core.warnambiguousrefs`, for the
62    // `:short` atoms' shorten_unambiguous_ref resolution.
63    pub ref_names: &'a HashSet<String>,
64    pub warn_ambiguous_refs: bool,
65}
66
67impl ForEachRefFormatContext<'_> {
68    /// Shorten a fully-qualified refname to its unambiguous abbreviation, the
69    /// way git's `%(refname:short)` / `%(symref:short)` / `%(upstream:short)` do.
70    pub fn shorten_ref(&self, refname: &str) -> String {
71        shorten_unambiguous_ref(refname, self.warn_ambiguous_refs, |candidate| {
72            self.ref_names.contains(candidate)
73        })
74    }
75}