macro_toolset/string_v2/general/
string.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Implementations for string.
//!
//! - &str
//! - &mut str
//! - &&str
//! - &mut &str
//! - &&mut str
//! - &mut &mut str
//! - Arc<str>
//! - Rc<str>
//! - Box<str>
//! - Cow<str>
//! - String
//! - &String
//! - &mut String
//! - &&String
//! - &mut &String

use std::{borrow::Cow, rc::Rc, sync::Arc};

use super::{StringExtT, StringT};
use crate::impl_for_shared_ref;

macro_rules! impl_for_string {
    ($($ty:ty),*) => {
        $(
            // So ugly, but it works.
            impl_for_string!(@INTERNAL $ty);
            impl_for_string!(@INTERNAL &$ty);
            impl_for_string!(@INTERNAL &mut $ty);
            impl_for_string!(@INTERNAL &&$ty);
            impl_for_string!(@INTERNAL &&mut $ty);
            impl_for_string!(@INTERNAL &mut &$ty);
            impl_for_string!(@INTERNAL &mut &mut $ty);
            impl_for_string!(@INTERNAL &&&$ty);
        )*
    };

    (@INTERNAL $ty:ty) => {
        impl StringT for $ty {
            #[inline]
            fn encode_to_buf(self, string: &mut Vec<u8>) {
                string.extend(self.as_bytes());
            }

            #[inline]
            fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
                string.extend(self.as_bytes());
                string.extend(separator.as_bytes());
            }

            #[inline]
            #[cfg(feature = "feat-string-ext-bytes")]
            fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
                string.extend(self.as_bytes());
            }

            #[inline]
            #[cfg(feature = "feat-string-ext-bytes")]
            fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
                string.extend(self.as_bytes());
                string.extend(separator.as_bytes());
            }
        }

        impl StringExtT for $ty {}
    }
}

impl_for_string! {
    &str,
    Arc<str>,
    Rc<str>,
    Box<str>,
    Cow<'_, str>,
    String
}

impl StringT for char {
    #[inline]
    fn encode_to_buf(self, string: &mut Vec<u8>) {
        // ! '�' != "�" in utf8 world. see [`String::push`].
        match self.len_utf8() {
            1 => string.push(self as u8),
            _ => string.extend(self.encode_utf8(&mut [0; 4]).as_bytes()),
        }
    }

    #[inline]
    fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
        self.encode_to_buf(string);
        string.extend(separator.as_bytes());
    }

    #[inline]
    #[cfg(feature = "feat-string-ext-bytes")]
    fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
        // ! '�' != "�" in utf8 world. see [`String::push`].
        match self.len_utf8() {
            1 => string.extend([self as u8]),
            _ => string.extend(self.encode_utf8(&mut [0; 4]).as_bytes()),
        }
    }

    #[cfg(feature = "feat-string-ext-bytes")]
    fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
        self.encode_to_bytes_buf(string);
        string.extend(separator.as_bytes());
    }
}

impl StringExtT for char {}

impl_for_shared_ref!(COPIED: char);