objects/util/line_diff/
mod.rs1mod compact;
5mod emit;
6mod myers;
7mod myers_search;
8mod scan;
9mod scratch;
10mod visit;
11
12#[cfg(test)]
13mod tests;
14
15use super::budget::{BudgetExceeded, ResourceUsage};
16
17pub use scratch::scratch_bytes_for_line_counts;
18pub use visit::visit_lcs_equal_runs;
19
20pub fn split_text_lines(bytes: &[u8]) -> Option<Vec<String>> {
22 let content = std::str::from_utf8(bytes).ok()?;
23 Some(content.lines().map(str::to_string).collect())
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct LineDiffLimits {
29 pub scratch_bytes: u64,
30 pub max_lines: u64,
31 pub max_work: u64,
32}
33
34impl LineDiffLimits {
35 pub fn unlimited() -> Self {
36 Self {
37 scratch_bytes: u64::MAX,
38 max_lines: u64::MAX,
39 max_work: u64::MAX,
40 }
41 }
42
43 pub fn budget(self, scratch_len: usize) -> crate::util::ResourceBudget {
44 crate::util::ResourceBudget::new(crate::util::ResourceUsage {
45 scratch_bytes: self.scratch_bytes.min(scratch_len as u64),
46 lines: self.max_lines,
47 work: self.max_work,
48 states: u64::MAX,
49 decoded_bytes: u64::MAX,
50 })
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct EqualRun {
57 pub old_start: usize,
58 pub new_start: usize,
59 pub len: usize,
60}
61
62#[derive(Debug)]
65pub enum LineDiffError<E = std::convert::Infallible> {
66 InvalidUtf8,
67 BudgetExceeded(BudgetExceeded),
68 Visitor(E),
69}
70
71impl<E> LineDiffError<E> {
72 pub fn from_budget(error: BudgetExceeded) -> Self {
73 Self::BudgetExceeded(error)
74 }
75}
76
77impl<E: std::fmt::Display> std::fmt::Display for LineDiffError<E> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 match self {
80 Self::InvalidUtf8 => f.write_str("input is not valid UTF-8"),
81 Self::BudgetExceeded(error) => write!(f, "{error}"),
82 Self::Visitor(error) => write!(f, "lcs visitor: {error}"),
83 }
84 }
85}
86
87impl<E: std::error::Error + 'static> std::error::Error for LineDiffError<E> {
88 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
89 match self {
90 Self::BudgetExceeded(error) => Some(error),
91 Self::Visitor(error) => Some(error),
92 Self::InvalidUtf8 => None,
93 }
94 }
95}
96
97impl<E> From<BudgetExceeded> for LineDiffError<E> {
98 fn from(error: BudgetExceeded) -> Self {
99 Self::BudgetExceeded(error)
100 }
101}
102
103pub type LcsVisitResult<E> = Result<ResourceUsage, LineDiffError<E>>;