|
8 | 8 |
|
9 | 9 |
|
10 | 10 | //! Abstraction that conditionally compiles either to rust-encoding,
|
11 |
| -//! or to only support UTF-8. |
| 11 | +//! encoding_rs or to only support UTF-8. |
12 | 12 |
|
13 | 13 | #[cfg(feature = "query_encoding")] extern crate encoding;
|
| 14 | +#[cfg(feature = "query_encoding_rs")] extern crate encoding_rs; |
14 | 15 |
|
15 | 16 | use std::borrow::Cow;
|
16 | 17 |
|
17 | 18 | #[cfg(feature = "query_encoding")] use self::encoding::types::{DecoderTrap, EncoderTrap};
|
18 | 19 | #[cfg(feature = "query_encoding")] use self::encoding::label::encoding_from_whatwg_label;
|
19 | 20 | #[cfg(feature = "query_encoding")] pub use self::encoding::types::EncodingRef;
|
20 | 21 |
|
| 22 | +#[cfg(feature = "query_encoding_rs")] use self::encoding_rs::UTF_8; |
| 23 | +#[cfg(feature = "query_encoding_rs")] pub use self::encoding_rs::Encoding; |
| 24 | +#[cfg(feature = "query_encoding_rs")] pub type EncodingRef = &'static Encoding; |
| 25 | + |
| 26 | + |
21 | 27 | #[cfg(feature = "query_encoding")]
|
22 | 28 | #[derive(Copy, Clone)]
|
23 | 29 | pub struct EncodingOverride {
|
@@ -90,11 +96,99 @@ impl EncodingOverride {
|
90 | 96 | }
|
91 | 97 |
|
92 | 98 |
|
93 |
| -#[cfg(not(feature = "query_encoding"))] |
| 99 | +#[cfg(feature = "query_encoding_rs")] |
| 100 | +#[derive(Copy, Clone)] |
| 101 | +pub struct EncodingOverride { |
| 102 | + encoding: &'static Encoding |
| 103 | +} |
| 104 | + |
| 105 | +#[cfg(feature = "query_encoding_rs")] |
| 106 | +impl EncodingOverride { |
| 107 | + pub fn from_opt_encoding(encoding: Option<&'static Encoding>) -> Self { |
| 108 | + encoding.map(Self::from_encoding).unwrap_or_else(Self::utf8) |
| 109 | + } |
| 110 | + |
| 111 | + pub fn from_encoding(encoding: &'static Encoding) -> Self { |
| 112 | + EncodingOverride { |
| 113 | + encoding: encoding |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + #[inline] |
| 118 | + pub fn utf8() -> Self { |
| 119 | + EncodingOverride { encoding: UTF_8 } |
| 120 | + } |
| 121 | + |
| 122 | + pub fn lookup(label: &[u8]) -> Option<Self> { |
| 123 | + Encoding::for_label(label).map(Self::from_encoding) |
| 124 | + } |
| 125 | + |
| 126 | + /// https://encoding.spec.whatwg.org/#get-an-output-encoding |
| 127 | + pub fn to_output_encoding(self) -> Self { |
| 128 | + Self::from_encoding(self.encoding.output_encoding()) |
| 129 | + } |
| 130 | + |
| 131 | + pub fn is_utf8(&self) -> bool { |
| 132 | + self.encoding == UTF_8 |
| 133 | + } |
| 134 | + |
| 135 | + pub fn name(&self) -> &'static str { |
| 136 | + self.encoding.name() |
| 137 | + } |
| 138 | + |
| 139 | + pub fn decode<'a>(&self, input: Cow<'a, [u8]>) -> Cow<'a, str> { |
| 140 | + match input { |
| 141 | + Cow::Borrowed(b) => { |
| 142 | + let (cow, _) = self.encoding.decode_without_bom_handling(b); |
| 143 | + return cow; |
| 144 | + } |
| 145 | + Cow::Owned(v) => { |
| 146 | + { |
| 147 | + let (cow, _) = self.encoding.decode_without_bom_handling(&v[..]); |
| 148 | + match cow { |
| 149 | + Cow::Owned(s) => { |
| 150 | + // Free old heap buffer and return a new one. |
| 151 | + return Cow::Owned(s); |
| 152 | + } |
| 153 | + Cow::Borrowed(_) => {} |
| 154 | + } |
| 155 | + } |
| 156 | + // Reuse the old heap buffer. |
| 157 | + return Cow::Owned(unsafe { String::from_utf8_unchecked(v) }); |
| 158 | + } |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + pub fn encode<'a>(&self, input: Cow<'a, str>) -> Cow<'a, [u8]> { |
| 163 | + match input { |
| 164 | + Cow::Borrowed(s) => { |
| 165 | + let (cow, _, _) = self.encoding.encode(s); |
| 166 | + return cow; |
| 167 | + } |
| 168 | + Cow::Owned(s) => { |
| 169 | + { |
| 170 | + let (cow, _, _) = self.encoding.encode(&s[..]); |
| 171 | + match cow { |
| 172 | + Cow::Owned(v) => { |
| 173 | + // Free old heap buffer and return a new one. |
| 174 | + return Cow::Owned(v); |
| 175 | + } |
| 176 | + Cow::Borrowed(_) => {} |
| 177 | + } |
| 178 | + } |
| 179 | + // Reuse the old heap buffer. |
| 180 | + return Cow::Owned(s.into_bytes()) |
| 181 | + } |
| 182 | + } |
| 183 | + } |
| 184 | +} |
| 185 | + |
| 186 | + |
| 187 | +#[cfg(not(any(feature = "query_encoding", feature = "query_encoding_rs")))] |
94 | 188 | #[derive(Copy, Clone)]
|
95 | 189 | pub struct EncodingOverride;
|
96 | 190 |
|
97 |
| -#[cfg(not(feature = "query_encoding"))] |
| 191 | +#[cfg(not(any(feature = "query_encoding", feature = "query_encoding_rs")))] |
98 | 192 | impl EncodingOverride {
|
99 | 193 | #[inline]
|
100 | 194 | pub fn utf8() -> Self {
|
@@ -127,6 +221,7 @@ pub fn decode_utf8_lossy(input: Cow<[u8]>) -> Cow<str> {
|
127 | 221 | }
|
128 | 222 | }
|
129 | 223 |
|
| 224 | +#[cfg(not(feature = "query_encoding_rs"))] |
130 | 225 | pub fn encode_utf8(input: Cow<str>) -> Cow<[u8]> {
|
131 | 226 | match input {
|
132 | 227 | Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()),
|
|
0 commit comments