pub(super) fn apply_stop_string_holdback(
new_chars: &str,
stop_strings: &[String],
buffer_len: usize,
accumulated_content: &mut String,
emitted_len: &mut usize,
triggered: &mut bool,
) -> String {
debug_assert!(!*triggered, "caller must gate on !triggered");
accumulated_content.push_str(new_chars);
let max_stop_len = stop_strings.iter().map(String::len).max().unwrap_or(0);
let search_start = {
let raw = accumulated_content
.len()
.saturating_sub(new_chars.len() + buffer_len + max_stop_len);
accumulated_content.floor_char_boundary(raw)
};
let matched_pos = stop_strings
.iter()
.filter_map(|s| accumulated_content[search_start..].find(s.as_str()))
.min()
.map(|rel| rel + search_start);
if let Some(pos) = matched_pos {
accumulated_content.truncate(pos);
let emit_start = (*emitted_len).min(pos);
let out = accumulated_content[emit_start..pos].to_string();
*emitted_len = pos;
*triggered = true;
return out;
}
let acc_len = accumulated_content.len();
let raw_emit_end = acc_len.saturating_sub(buffer_len);
let emit_end = accumulated_content.floor_char_boundary(raw_emit_end);
let emit_start = (*emitted_len).min(emit_end);
let out = accumulated_content[emit_start..emit_end].to_string();
*emitted_len = emit_end;
out
}