#![deny(missing_docs)]
pub fn chunk(src: &str, max_chars: usize) -> Vec<String> {
let blocks = split_top_level_blocks(src);
let mut out = Vec::new();
let mut buf = String::new();
for block in blocks {
if buf.len() + block.len() <= max_chars {
buf.push_str(&block);
} else {
if !buf.is_empty() {
out.push(std::mem::take(&mut buf));
}
out.push(block);
}
}
if !buf.is_empty() {
out.push(buf);
}
out
}
fn split_top_level_blocks(src: &str) -> Vec<String> {
let mut out: Vec<String> = Vec::new();
let mut buf = String::new();
let mut depth: i32 = 0;
for line in src.split_inclusive('\n') {
buf.push_str(line);
let trimmed = line.trim();
for c in trimmed.chars() {
match c {
'{' => depth += 1,
'}' => {
if depth > 0 {
depth -= 1;
}
}
_ => {}
}
}
if depth == 0 && trimmed.ends_with('}') {
out.push(std::mem::take(&mut buf));
}
}
if !buf.is_empty() {
out.push(buf);
}
out
}