Lines of
src/utils.rs
from check-in 3c858ed7c4
that are changed by the sequence of edits moving toward
check-in bf99298edf:
1: use crate::Cursor;
2:
3: use std::borrow::Cow;
4:
5: use html_escape::encode_text;
6: use lazy_static::lazy_static;
3c858ed7c4 2026-07-31 7: use regex::Regex;
8: use stacked_errors::{
9: bail,
10: Result,
11: };
12:
13: lazy_static! {
14: pub static ref RE_DOMAIN: Regex = Regex::new(r"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$").expect("Invalid domain regex");
3c858ed7c4 2026-07-31 15: pub static ref RE_CLOSING: Regex = Regex::new(r"</[ \t]*(pre|code)[ \t]*>").expect("Invalid cloding tag regex");
16: }
17:
18: /// Stores binary attachment data and metadata for Telegram messages.
19: /// The data is wrapped in a `Cursor<Vec<u8>>` for efficient streaming,
20: /// while `name` holds the filename or display name of the attachment.
21: #[derive(Debug)]
22: pub struct Attachment {
23: pub data: Cursor<Vec<u8>>,
24: pub name: String,
25: }
26:
27: /// Pass any text here to be validated as not breaking from Telegram preformatted blocks
28: /// escape all HTML chars afterwards
29: pub fn validate <'a>(text: &'a str) -> Result<Cow<'a, str>> {
30: if RE_CLOSING.is_match(text) {
31: bail!("Telegram closing tag found.");
32: } else {
33: Ok(encode_text(text))
34: }
35: }