>", &detail.content_hash);
let pattern = placeholder_str.as_bytes();
let pattern_len = pattern.len();
let mut search_cursor = 0;
while let Some(pos) = restored_eml[search_cursor..]
.windows(pattern_len)
.position(|window| window == pattern)
{
let absolute_start = search_cursor + pos;
let absolute_end = absolute_start + pattern_len;
tasks.push((
absolute_start,
absolute_end,
detail.content_hash.clone(),
));
search_cursor = absolute_end;
}
}
tasks.sort_by(|a, b| b.0.cmp(&a.0));
for (start, end, hash) in tasks {
if let Some(original_data) = BLOB_MANAGER.get_attachment(&hash)? {
restored_eml.splice(start..end, original_data.iter().cloned());
} else {
error!("[ERROR] Missing attachment blob for hash: {}", hash);
}
}
Ok((e.envelope, Bytes::from(restored_eml)))
}
#[cfg(test)]
mod test {
use html2text::config;
#[test]
fn test_various_html_with_overflow_enabled() {
let cases = [
("Hello World
", "Simple paragraph"),
("Title
Content
", "Heading + paragraph"),
("", "Unordered list"),
(
"Bold and italic",
"Inline formatting",
),
(
"Nested elements
",
"Nested inline elements inside block",
),
(
"",
"Simple table",
),
(
" preformatted text\n line2
",
"Preformatted block",
),
("😃 emoji test", "Wide emoji"),
("link", "Anchor tag"),
(
"Quoted text
",
"Blockquote with paragraph",
),
];
for (html, desc) in cases {
let result = config::plain()
.allow_width_overflow()
.string_from_read(html.as_bytes(), 100);
match result {
Ok(output) => {
println!("✓ Rendered ({}) =>\n{}", desc, output);
}
Err(e) => panic!("Unexpected error for {}: {:?}", desc, e),
}
}
}
}