macro_toolset/string/
externs.rs

1//! Implementations of extern crate types
2
3macro_rules! impl_for_extern_type {
4    ($(#[$outer:meta])* $type:ty: $self:ident, $arg:ident => $block:block) => {
5        $(#[$outer])*
6        impl super::StringT for $type {
7            #[inline]
8            fn encode_to_buf($self: Self, $arg: &mut Vec<u8>) $block
9
10            #[inline]
11            fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, _separator: &str) {
12                self.encode_to_buf(string);
13            }
14
15            #[inline]
16            fn encode_to_bytes_buf($self: Self, $arg: &mut bytes::BytesMut) $block
17
18            #[inline]
19            fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, _separator: &str) {
20                self.encode_to_bytes_buf(string);
21            }
22        }
23
24        $(#[$outer])*
25        impl super::StringExtT for $type {}
26    };
27}
28
29#[cfg(feature = "feat-string-ext-ammonia")]
30impl super::StringT for ammonia::Document {
31    #[inline]
32    fn encode_to_buf(self, string: &mut Vec<u8>) {
33        self.write_to(string)
34            .expect("Writing to a string should not fail (except on OOM)");
35    }
36
37    #[inline]
38    fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, _separator: &str) {
39        self.encode_to_buf(string);
40    }
41
42    #[inline]
43    fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
44        use bytes::BufMut;
45
46        self.write_to(string.writer())
47            .expect("Writing to a string should not fail (except on OOM)");
48    }
49
50    #[inline]
51    fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, _separator: &str) {
52        self.encode_to_bytes_buf(string);
53    }
54}
55
56#[cfg(feature = "feat-string-ext-chrono")]
57impl<'a, I: Iterator<Item = B> + Clone, B: std::borrow::Borrow<chrono::format::Item<'a>>>
58    super::StringT for chrono::format::DelayedFormat<I>
59{
60    #[inline]
61    fn encode_to_buf(self, string: &mut Vec<u8>) {
62        // TODO: Avoid allocation here, though chrono doesn't provide a way to do so.
63        string.extend(self.to_string().as_bytes());
64    }
65
66    #[inline]
67    fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, _separator: &str) {
68        self.encode_to_buf(string);
69    }
70
71    #[inline]
72    fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
73        // TODO: Avoid allocation here, though chrono doesn't provide a way to do so.
74        string.extend(self.to_string().as_bytes());
75    }
76
77    #[inline]
78    fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, _separator: &str) {
79        self.encode_to_bytes_buf(string);
80    }
81}
82
83impl_for_extern_type! {
84    #[cfg(feature = "feat-string-ext-http")]
85    http::HeaderName: self, string => {
86        string.extend(self.as_str().as_bytes());
87    }
88}
89
90impl_for_extern_type! {
91    #[cfg(feature = "feat-string-ext-http")]
92    http::Method: self, string => {
93        string.extend(self.as_str().as_bytes());
94    }
95}
96
97impl_for_extern_type! {
98    #[cfg(feature = "feat-string-ext-http")]
99    http::StatusCode: self, string => {
100        string.extend(self.as_str().as_bytes());
101    }
102}
103
104impl_for_extern_type! {
105    #[cfg(feature = "feat-string-ext-http")]
106    http::Uri: self, string => {
107        if let Some(scheme) = self.scheme() {
108            string.extend(scheme.as_str().as_bytes());
109            string.extend(b"://");
110        }
111
112        if let Some(authority) = self.authority() {
113            string.extend(authority.as_str().as_bytes());
114        }
115
116        string.extend(self.path().as_bytes());
117
118        if let Some(query) = self.query() {
119            string.extend(b"?");
120            string.extend(query.as_bytes());
121        }
122    }
123}
124
125impl_for_extern_type! {
126    #[cfg(feature = "feat-string-ext-http")]
127    http::Version: self, string => {
128        let str_byte = match self {
129            http::Version::HTTP_09 => &b"HTTP/0.9"[..],
130            http::Version::HTTP_10 => &b"HTTP/1.0"[..],
131            http::Version::HTTP_11 => &b"HTTP/1.1"[..],
132            http::Version::HTTP_2 => &b"HTTP/2.0"[..],
133            http::Version::HTTP_3 => &b"HTTP/3.0"[..],
134            _ => {
135                string.extend(format!("{self:?}").as_bytes());
136                return;
137            }
138        };
139
140        string.extend(str_byte);
141    }
142}