const LEAD: usize = 40;
const WIDTH: usize = 160;
const ELISION: char = '…';
pub fn excerpt(text: &str, offset: usize) -> String {
let offset = offset.min(text.len());
let start = text
.get(..offset)
.and_then(|head| head.rfind('\n'))
.map_or(0, |i| i + 1);
let end = text
.get(offset..)
.and_then(|tail| tail.find('\n'))
.map_or(text.len(), |i| offset + i);
let line = text.get(start..end).unwrap_or_default();
let from = boundary(line, offset.saturating_sub(start).saturating_sub(LEAD));
let to = boundary(line, from.saturating_add(WIDTH));
let mut out = String::new();
if from > 0 {
out.push(ELISION);
}
out.push_str(line.get(from..to).unwrap_or_default().trim());
if to < line.len() {
out.push(ELISION);
}
out
}
fn boundary(text: &str, at: usize) -> usize {
if at >= text.len() {
return text.len();
}
text.char_indices()
.map(|(i, _)| i)
.take_while(|i| *i <= at)
.last()
.unwrap_or(0)
}