summaryrefslogtreecommitdiff
path: root/src/util/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/mod.rs')
-rw-r--r--src/util/mod.rs64
1 files changed, 45 insertions, 19 deletions
diff --git a/src/util/mod.rs b/src/util/mod.rs
index a3fad8ca..1eb19113 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -11,7 +11,6 @@ use std::hash::Hash;
use std::path::{Component, Path, PathBuf};
use std::sync::Arc;
-use ecow::EcoString;
use siphasher::sip128::{Hasher128, SipHasher};
/// Turn a closure into a struct implementing [`Debug`].
@@ -133,30 +132,38 @@ impl PathExt for Path {
}
}
-/// Format something as a a comma-separated list that support horizontal
-/// formatting but falls back to vertical formatting if the pieces are too long.
-pub fn pretty_array(pieces: &[EcoString], trailing_comma: bool) -> String {
- let list = pretty_comma_list(&pieces, trailing_comma);
+/// Format pieces separated with commas and a final "and" or "or".
+pub fn separated_list(pieces: &[impl AsRef<str>], last: &str) -> String {
let mut buf = String::new();
- buf.push('(');
- if list.contains('\n') {
- buf.push('\n');
- buf.push_str(&indent(&list, 2));
- buf.push('\n');
- } else {
- buf.push_str(&list);
+ for (i, part) in pieces.iter().enumerate() {
+ match i {
+ 0 => {}
+ 1 if pieces.len() == 2 => {
+ buf.push(' ');
+ buf.push_str(last);
+ buf.push(' ');
+ }
+ i if i + 1 == pieces.len() => {
+ buf.push_str(", ");
+ buf.push_str(last);
+ buf.push(' ');
+ }
+ _ => buf.push_str(", "),
+ }
+ buf.push_str(part.as_ref());
}
- buf.push(')');
buf
}
-/// Format something as a a comma-separated list that support horizontal
-/// formatting but falls back to vertical formatting if the pieces are too long.
-pub fn pretty_comma_list(pieces: &[EcoString], trailing_comma: bool) -> String {
+/// Format a comma-separated list.
+///
+/// Tries to format horizontally, but falls back to vertical formatting if the
+/// pieces are too long.
+pub fn pretty_comma_list(pieces: &[impl AsRef<str>], trailing_comma: bool) -> String {
const MAX_WIDTH: usize = 50;
let mut buf = String::new();
- let len = pieces.iter().map(|s| s.len()).sum::<usize>()
+ let len = pieces.iter().map(|s| s.as_ref().len()).sum::<usize>()
+ 2 * pieces.len().saturating_sub(1);
if len <= MAX_WIDTH {
@@ -164,14 +171,14 @@ pub fn pretty_comma_list(pieces: &[EcoString], trailing_comma: bool) -> String {
if i > 0 {
buf.push_str(", ");
}
- buf.push_str(piece);
+ buf.push_str(piece.as_ref());
}
if trailing_comma {
buf.push(',');
}
} else {
for piece in pieces {
- buf.push_str(piece.trim());
+ buf.push_str(piece.as_ref().trim());
buf.push_str(",\n");
}
}
@@ -179,6 +186,25 @@ pub fn pretty_comma_list(pieces: &[EcoString], trailing_comma: bool) -> String {
buf
}
+/// Format an array-like construct.
+///
+/// Tries to format horizontally, but falls back to vertical formatting if the
+/// pieces are too long.
+pub fn pretty_array_like(parts: &[impl AsRef<str>], trailing_comma: bool) -> String {
+ let list = pretty_comma_list(&parts, trailing_comma);
+ let mut buf = String::new();
+ buf.push('(');
+ if list.contains('\n') {
+ buf.push('\n');
+ buf.push_str(&indent(&list, 2));
+ buf.push('\n');
+ } else {
+ buf.push_str(&list);
+ }
+ buf.push(')');
+ buf
+}
+
/// Indent a string by two spaces.
pub fn indent(text: &str, amount: usize) -> String {
let mut buf = String::new();