Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/stdx/src/lib.rs')
-rw-r--r--crates/stdx/src/lib.rs57
1 files changed, 51 insertions, 6 deletions
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs
index 7ab26b1890..a1af4cc6be 100644
--- a/crates/stdx/src/lib.rs
+++ b/crates/stdx/src/lib.rs
@@ -221,12 +221,7 @@ pub fn trim_indent(mut text: &str) -> String {
if text.starts_with('\n') {
text = &text[1..];
}
- let indent = text
- .lines()
- .filter(|it| !it.trim().is_empty())
- .map(|it| it.len() - it.trim_start().len())
- .min()
- .unwrap_or(0);
+ let indent = indent_of(text);
text.split_inclusive('\n')
.map(
|line| {
@@ -236,6 +231,25 @@ pub fn trim_indent(mut text: &str) -> String {
.collect()
}
+#[must_use]
+fn indent_of(text: &str) -> usize {
+ text.lines()
+ .filter(|it| !it.trim().is_empty())
+ .map(|it| it.len() - it.trim_start().len())
+ .min()
+ .unwrap_or(0)
+}
+
+#[must_use]
+pub fn dedent_by(spaces: usize, text: &str) -> String {
+ text.split_inclusive('\n')
+ .map(|line| {
+ let trimmed = line.trim_start_matches(' ');
+ if line.len() - trimmed.len() <= spaces { trimmed } else { &line[spaces..] }
+ })
+ .collect()
+}
+
pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize>
where
F: FnMut(&T) -> Ordering,
@@ -367,6 +381,37 @@ mod tests {
}
#[test]
+ fn test_dedent() {
+ assert_eq!(dedent_by(0, ""), "");
+ assert_eq!(dedent_by(1, ""), "");
+ assert_eq!(dedent_by(2, ""), "");
+ assert_eq!(dedent_by(0, "foo"), "foo");
+ assert_eq!(dedent_by(2, "foo"), "foo");
+ assert_eq!(dedent_by(2, " foo"), "foo");
+ assert_eq!(dedent_by(2, " foo"), " foo");
+ assert_eq!(dedent_by(2, " foo\nbar"), " foo\nbar");
+ assert_eq!(dedent_by(2, "foo\n bar"), "foo\n bar");
+ assert_eq!(dedent_by(2, "foo\n\n bar"), "foo\n\n bar");
+ assert_eq!(dedent_by(2, "foo\n.\n bar"), "foo\n.\n bar");
+ assert_eq!(dedent_by(2, "foo\n .\n bar"), "foo\n.\n bar");
+ assert_eq!(dedent_by(2, "foo\n .\n bar"), "foo\n .\n bar");
+ }
+
+ #[test]
+ fn test_indent_of() {
+ assert_eq!(indent_of(""), 0);
+ assert_eq!(indent_of(" "), 0);
+ assert_eq!(indent_of(" x"), 1);
+ assert_eq!(indent_of(" x\n"), 1);
+ assert_eq!(indent_of(" x\ny"), 0);
+ assert_eq!(indent_of(" x\n y"), 1);
+ assert_eq!(indent_of(" x\n y"), 1);
+ assert_eq!(indent_of(" x\n y"), 2);
+ assert_eq!(indent_of(" x\n y\n"), 2);
+ assert_eq!(indent_of(" x\n\n y\n"), 2);
+ }
+
+ #[test]
fn test_replace() {
#[track_caller]
fn test_replace(src: &str, from: char, to: &str, expected: &str) {