ruma_events/room/message/
sanitize.rs

1//! Convenience methods and types to sanitize text messages.
2
3/// Remove the [rich reply] fallback of the given plain text string.
4///
5/// [rich reply]: https://spec.matrix.org/latest/client-server-api/#rich-replies
6pub fn remove_plain_reply_fallback(mut s: &str) -> &str {
7    // A reply fallback must begin with a mention of the original sender between `<` and `>`, and
8    // emotes add `*` as a prefix. If there is no newline, removing the detected fallback would
9    // result in an empty string.
10    if (!s.starts_with("> <") && !s.starts_with("> * <")) || !s.contains('\n') {
11        return s;
12    }
13
14    while s.starts_with("> ") {
15        if let Some((_line, rest)) = s.split_once('\n') {
16            s = rest;
17        } else {
18            return "";
19        }
20    }
21
22    // Strip the first line after the fallback if it is empty.
23    if let Some(rest) = s.strip_prefix('\n') { rest } else { s }
24}
25
26#[cfg(test)]
27mod tests {
28    use super::remove_plain_reply_fallback;
29
30    #[test]
31    fn remove_plain_reply() {
32        assert_eq!(
33            remove_plain_reply_fallback("No reply here\nJust a simple message"),
34            "No reply here\nJust a simple message"
35        );
36
37        assert_eq!(
38            remove_plain_reply_fallback(
39                "> <@user:notareal.hs> Replied to on\n\
40                 > two lines\n\
41                 \n\
42                 \n\
43                 This is my reply"
44            ),
45            "\nThis is my reply"
46        );
47
48        assert_eq!(remove_plain_reply_fallback("\n> Not on first line"), "\n> Not on first line");
49
50        assert_eq!(
51            remove_plain_reply_fallback("> <@user:notareal.hs> Previous message\n\n> New quote"),
52            "> New quote"
53        );
54    }
55}