use std::borrow::Cow;
use handlebars::{
no_escape, Context, Handlebars, Helper, HelperDef, HelperResult, Output, RenderContext,
Renderable, StringOutput,
};
fn word_wrap_acc<'a>(
mut acc: Vec<Cow<'a, str>>,
word: &'a str,
line_length: usize,
) -> Vec<Cow<'a, str>> {
let length = acc.len();
if length != 0 {
let last_line = acc.last().unwrap();
if last_line.len() + word.len() < line_length {
acc[length - 1] = format!("{} {}", last_line, word).into();
} else {
acc.push(word.into());
}
} else {
acc.push(word.into());
}
acc
}
fn word_wrap(s: &str, line_length: usize) -> String {
s.split(' ')
.fold(Vec::new(), |acc, word| {
word_wrap_acc(acc, word, line_length - 2)
})
.join("\n")
}
struct WordWrapBlock {
max: usize,
disabled: bool,
}
impl HelperDef for WordWrapBlock {
fn call<'reg: 'rc, 'rc>(
&self,
h: &Helper<'rc>,
r: &'reg Handlebars<'reg>,
ctx: &'rc Context,
rc: &mut RenderContext<'reg, 'rc>,
out: &mut dyn Output,
) -> HelperResult {
let mut unwrapped = StringOutput::new();
h.template()
.map(|t| t.render(r, ctx, rc, &mut unwrapped))
.unwrap_or(Ok(()))?;
let unwrapped = unwrapped.into_string()?;
let unwrapped = unwrapped.as_str();
if self.disabled {
out.write(unwrapped)?;
} else {
let wrapped = word_wrap(unwrapped, self.max);
out.write(&wrapped)?;
}
Ok(())
}
}
pub fn new(max: usize, disabled: bool) -> Handlebars<'static> {
let mut handlebars = Handlebars::new();
handlebars.set_strict_mode(true);
handlebars.register_escape_fn(no_escape);
handlebars.register_helper("word-wrap", Box::new(WordWrapBlock { max, disabled }));
handlebars
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_word_wrap_block() {
let template =
r#"{{#word-wrap max=8}}The quick brown fox jumps over the lazy dog{{/word-wrap}}"#;
let mut handlebars = Handlebars::new();
handlebars.register_helper(
"word-wrap",
Box::new(WordWrapBlock {
max: 8,
disabled: false,
}),
);
let result = handlebars.render_template(template, &()).unwrap();
assert_eq!(
result,
"The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog"
)
}
#[test]
fn test_word_wrap() {
let s = "The quick brown fox jumps over the lazy dog";
assert_eq!(word_wrap(s, 80), s);
assert_eq!(
word_wrap(s, 8),
"The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog"
);
}
}