fn push_values<'s, T: DiffableStr + ?Sized>(
v: &mut Vec<Vec<(bool, &'s T)>>,
idx: usize,
emphasized: bool,
s: &'s T,
) {
v.resize_with(v.len().max(idx + 1), Vec::new); // newlines cause all kinds of wacky stuff if they end up highlighted. // because of this we want to unemphasize all newlines we encounter. if emphasized { for seg in s.tokenize_lines_and_newlines() {
v[idx].push((!seg.ends_with_newline(), seg));
}
} else {
v[idx].push((false, s));
}
}
/// Represents the expanded textual change with inline highlights. /// /// This is like [`Change`] but with inline highlight info. #[derive(Debug, PartialEq, Eq, Hash, Clone, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] pubstruct InlineChange<'s, T: DiffableStr + ?Sized> {
tag: ChangeTag,
old_index: Option<usize>,
new_index: Option<usize>,
values: Vec<(bool, &'s T)>,
}
/// Returns the old index if available. pubfn old_index(&self) -> Option<usize> { self.old_index
}
/// Returns the new index if available. pubfn new_index(&self) -> Option<usize> { self.new_index
}
/// Returns the changed values. /// /// Each item is a tuple in the form `(emphasized, value)` where `emphasized` /// is true if it should be highlighted as an inline diff. /// /// Depending on the type of the underlying [`DiffableStr`] this value is /// more or less useful. If you always want to have a utf-8 string it's /// better to use the [`InlineChange::iter_strings_lossy`] method. pubfn values(&self) -> &[(bool, &'s T)] {
&self.values
}
/// Iterates over all (potentially lossy) utf-8 decoded values. /// /// Each item is a tuple in the form `(emphasized, value)` where `emphasized` /// is true if it should be highlighted as an inline diff. /// /// By default, words are split by whitespace, which results in coarser diff. /// For example: `"f(x) y"` is tokenized as `["f(x)", "y"]`. /// /// If you want it to be tokenized instead as `["f(", "x", ")"]`, /// you should enable the `"unicode"` flag. pubfn iter_strings_lossy(&self) -> impl Iterator<Item = (bool, Cow<'_, str>)> { self.values()
.iter()
.map(|(emphasized, raw_value)| (*emphasized, raw_value.to_string_lossy()))
}
/// Returns `true` if this change does not end in a newline and must be /// followed up by one if line based diffs are used. pubfn missing_newline(&self) -> bool {
!self.values.last().map_or(true, |x| x.1.ends_with_newline())
}
}
#[test] fn test_line_ops_inline() { let diff = TextDiff::from_lines( "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff", "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n",
);
assert!(diff.newline_terminated()); let changes = diff
.ops()
.iter()
.flat_map(|op| diff.iter_inline_changes(op))
.collect::<Vec<_>>();
insta::assert_debug_snapshot!(&changes);
}
#[test] #[cfg(feature = "serde")] fn test_serde() { let diff = TextDiff::from_lines( "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff", "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n",
);
assert!(diff.newline_terminated()); let changes = diff
.ops()
.iter()
.flat_map(|op| diff.iter_inline_changes(op))
.collect::<Vec<_>>(); let json = serde_json::to_string_pretty(&changes).unwrap();
insta::assert_snapshot!(&json);
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.1Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.