Skip to main content

sley_diff_format/
hunks.rs

1use sley_diff_merge::render::{HunkWordDiff, RenderColors};
2
3use crate::{CompiledFuncname, DiffColors, WordDiffBuffers, WordDiffConfig};
4
5/// Map a diff color palette into the engine's render-color borrow.
6pub fn render_colors(colors: &DiffColors) -> RenderColors<'_> {
7    RenderColors {
8        frag: &colors.frag,
9        func: &colors.func,
10        old: &colors.old,
11        new: &colors.new,
12        context: &colors.context,
13        reset: &colors.reset,
14        whitespace: &colors.whitespace,
15        old_moved: &colors.old_moved,
16        old_moved_alt: &colors.old_moved_alt,
17        old_moved_dim: &colors.old_moved_dim,
18        old_moved_alt_dim: &colors.old_moved_alt_dim,
19        new_moved: &colors.new_moved,
20        new_moved_alt: &colors.new_moved_alt,
21        new_moved_dim: &colors.new_moved_dim,
22        new_moved_alt_dim: &colors.new_moved_alt_dim,
23    }
24}
25
26/// Bridge a word-diff config + its line buffers into the engine's
27/// [`HunkWordDiff`] hook. The engine owns hunk shaping; this adapter owns the
28/// word-level rendering.
29pub struct WordDiffAdapter<'a> {
30    config: &'a WordDiffConfig<'a>,
31    buffers: WordDiffBuffers,
32}
33
34impl<'a> WordDiffAdapter<'a> {
35    pub fn new(config: &'a WordDiffConfig<'a>) -> Self {
36        Self {
37            config,
38            buffers: WordDiffBuffers::new(),
39        }
40    }
41}
42
43impl HunkWordDiff for WordDiffAdapter<'_> {
44    fn push_minus(&mut self, content: &[u8]) {
45        self.buffers.push_minus(content);
46    }
47
48    fn push_plus(&mut self, content: &[u8]) {
49        self.buffers.push_plus(content);
50    }
51
52    fn flush(&mut self, out: &mut Vec<u8>) {
53        self.buffers.flush(out, self.config);
54    }
55
56    fn emit_context_line(&mut self, out: &mut Vec<u8>, content: &[u8]) {
57        WordDiffBuffers::emit_context_line(out, self.config, content);
58    }
59}
60
61/// A per-line section-heading classifier matching git's funcname resolution:
62/// a userdiff `xfuncname` pattern when a driver is present, else the default
63/// `def_ff` heuristic.
64pub fn heading_classifier<'a>(
65    funcname: Option<&'a CompiledFuncname>,
66) -> impl FnMut(&[u8]) -> Option<Vec<u8>> + 'a {
67    move |line: &[u8]| match funcname {
68        Some(funcname) => funcname.match_line(line),
69        None => crate::default_funcname_heading(line),
70    }
71}
72