v_escape/
chars.rs

1#[macro_export]
2#[doc(hidden)]
3macro_rules! escape_char {
4    ($($t:tt)+) => {
5        pub fn escape_char(c: char, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
6            if c.is_ascii() {
7                macro_rules! _inside {
8                    (impl one $byte:ident, $quote:ident) => {
9                        if $byte == c as u8 {
10                            return fmt.write_str($quote)
11                        }
12                    };
13                    (impl $T:ident, $Q:ident, $Q_LEN:ident) => {
14                        let c = $T[c as usize] as usize;
15                        if c < $Q_LEN {
16                          return fmt.write_str($Q[c]);
17                        }
18                    };
19                }
20
21                _inside!(impl $($t)+);
22            }
23
24            use std::fmt::Write;
25            fmt.write_char(c)
26        }
27    };
28}
29
30#[macro_export]
31#[doc(hidden)]
32macro_rules! escape_char_ptr {
33    ($($t:tt)+) => {
34        pub unsafe fn f_escape_char(c: char, buf: &mut [std::mem::MaybeUninit<u8>]) -> Option<usize> {
35            let len = c.len_utf8();
36            if len == 1 {
37                macro_rules! _inside {
38                    (impl one $byte:ident, $quote:ident) => {
39                        if $byte == c as u8 {
40                            let mut buf_cur = 0;
41                            $crate::write_ptr!(buf_cur, buf, ($quote.as_bytes() as *const _ as *const u8), $quote.len());
42                            return Some(buf_cur);
43                        }
44                    };
45                    (impl $T:ident, $Q:ident, $Q_LEN:ident) => {
46                        let c = $T[c as usize] as usize;
47                        if c < $Q_LEN {
48                            let mut buf_cur = 0;
49                            let quote = $Q[c];
50                            $crate::write_ptr!(buf_cur, buf, (quote.as_bytes() as *const _ as *const u8), quote.len());
51                            return Some(buf_cur);
52                        }
53                    };
54                }
55
56                _inside!(impl $($t)+);
57                // Ascii length is one byte
58                if 0 < buf.len() {
59                    *buf.as_mut_ptr() = std::mem::MaybeUninit::new(c as u8);
60                    Some(1)
61                } else {
62                    None
63                }
64            } else if len < buf.len() {
65                // safety, encode_utf8 not read
66                Some(c.encode_utf8(std::mem::transmute(buf)).len())
67            } else {
68                None
69            }
70        }
71    };
72}
73
74#[macro_export]
75#[doc(hidden)]
76macro_rules! escape_char_bytes {
77    ($($t:tt)+) => {
78        pub unsafe fn b_escape_char<B: $crate::Buffer>(c: char, buf: &mut B) {
79            let len = c.len_utf8();
80            buf.reserve(len);
81            if len == 1 {
82                macro_rules! _inside {
83                    (impl one $byte:ident, $quote:ident) => {
84                        if $byte == c as u8 {
85                            $crate::write_bytes!($quote.as_bytes(), buf);
86                            return;
87                        }
88                    };
89                    (impl $T:ident, $Q:ident, $Q_LEN:ident) => {
90                        let c = $T[c as usize] as usize;
91                        if c < $Q_LEN {
92                            $crate::write_bytes!($Q[c].as_bytes(), buf);
93                            return;
94                        }
95                    };
96                }
97
98                _inside!(impl $($t)+);
99                *buf.buf_ptr() = c as u8;
100            } else {
101                c.encode_utf8(std::slice::from_raw_parts_mut(buf.buf_ptr(), len));
102            }
103            buf.advance(len);
104        }
105    };
106}