diff options
Diffstat (limited to 'src/util/mod.rs')
| -rw-r--r-- | src/util/mod.rs | 64 |
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(); |
