email_parser/
string.rs

1use std::borrow::Cow;
2
3#[inline]
4pub(crate) fn empty_string() -> Cow<'static, str> {
5    Cow::Borrowed("")
6}
7
8#[inline]
9pub(crate) fn from_slice(slice: &[u8]) -> Cow<str> {
10    unsafe { Cow::Borrowed(std::str::from_utf8_unchecked(slice)) }
11}
12
13#[inline]
14pub(crate) fn add_string<'a, 'b>(s1: &'b mut Cow<'a, str>, s2: Cow<'a, str>) {
15    match s1 {
16        Cow::Borrowed(data1) => {
17            if let Cow::Borrowed(data2) = s2 {
18                if data2.is_empty() {
19                    return;
20                }
21                if data1.is_empty() {
22                    *data1 = data2;
23                    return;
24                }
25                // if the two references are consecutive in memory, we create a third reference containing them
26                unsafe {
27                    if data1.as_ptr().add(data1.len()) == data2.as_ptr() {
28                        // this is what guarantee safety
29                        let slice =
30                            std::slice::from_raw_parts(data1.as_ptr(), data1.len() + data2.len());
31                        *data1 = std::str::from_utf8_unchecked(slice);
32                        return;
33                    }
34                }
35            }
36            *s1 = Cow::Owned(s1.to_string() + &s2);
37        }
38        Cow::Owned(ref mut string) => {
39            string.push_str(&s2);
40        }
41    }
42}
43
44#[inline]
45pub(crate) fn add_str<'a, 'b>(s1: &'b mut Cow<'a, str>, s2: &'a str) {
46    match s1 {
47        Cow::Borrowed(data1) => {
48            if s2.is_empty() {
49                return;
50            }
51            if data1.is_empty() {
52                *data1 = s2;
53                return;
54            }
55            // if the two references are consecutive in memory, we create a third reference containing them
56            unsafe {
57                if data1.as_ptr().add(data1.len()) == s2.as_ptr() {
58                    // this is what guarantee safety
59                    let slice = std::slice::from_raw_parts(data1.as_ptr(), data1.len() + s2.len());
60                    *data1 = std::str::from_utf8_unchecked(slice);
61                    return;
62                }
63            }
64            *s1 = Cow::Owned(s1.to_string() + s2);
65        }
66        Cow::Owned(ref mut string) => {
67            string.push_str(&s2);
68        }
69    }
70}