mail_parser/decoders/charsets/
multi_byte.rs

1/*
2 * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
3 *
4 * SPDX-License-Identifier: Apache-2.0 OR MIT
5 */
6
7#[cfg(feature = "full_encoding")]
8use encoding_rs::*;
9
10#[cfg(feature = "full_encoding")]
11fn multi_byte_decoder(mut decoder: Decoder, bytes: &[u8]) -> String {
12    let mut result = String::with_capacity(bytes.len() * 4);
13
14    if let (CoderResult::OutputFull, _, _) = decoder.decode_to_string(bytes, &mut result, true) {
15        debug_assert!(false, "String full while decoding.")
16    }
17
18    result.shrink_to_fit();
19    result
20}
21
22#[inline(always)]
23pub(crate) fn decoder_shift_jis(bytes: &[u8]) -> String {
24    #[cfg(feature = "full_encoding")]
25    {
26        multi_byte_decoder(SHIFT_JIS.new_decoder(), bytes)
27    }
28
29    #[cfg(not(feature = "full_encoding"))]
30    {
31        String::from_utf8_lossy(bytes).into_owned()
32    }
33}
34
35#[inline(always)]
36pub(crate) fn decoder_big5(bytes: &[u8]) -> String {
37    #[cfg(feature = "full_encoding")]
38    {
39        multi_byte_decoder(BIG5.new_decoder(), bytes)
40    }
41
42    #[cfg(not(feature = "full_encoding"))]
43    {
44        String::from_utf8_lossy(bytes).into_owned()
45    }
46}
47
48#[inline(always)]
49pub(crate) fn decoder_euc_jp(bytes: &[u8]) -> String {
50    #[cfg(feature = "full_encoding")]
51    {
52        multi_byte_decoder(EUC_JP.new_decoder(), bytes)
53    }
54
55    #[cfg(not(feature = "full_encoding"))]
56    {
57        String::from_utf8_lossy(bytes).into_owned()
58    }
59}
60
61#[inline(always)]
62pub(crate) fn decoder_euc_kr(bytes: &[u8]) -> String {
63    #[cfg(feature = "full_encoding")]
64    {
65        multi_byte_decoder(EUC_KR.new_decoder(), bytes)
66    }
67
68    #[cfg(not(feature = "full_encoding"))]
69    {
70        String::from_utf8_lossy(bytes).into_owned()
71    }
72}
73
74#[inline(always)]
75pub(crate) fn decoder_gb18030(bytes: &[u8]) -> String {
76    #[cfg(feature = "full_encoding")]
77    {
78        multi_byte_decoder(GB18030.new_decoder(), bytes)
79    }
80
81    #[cfg(not(feature = "full_encoding"))]
82    {
83        String::from_utf8_lossy(bytes).into_owned()
84    }
85}
86
87#[inline(always)]
88pub(crate) fn decoder_gbk(bytes: &[u8]) -> String {
89    #[cfg(feature = "full_encoding")]
90    {
91        multi_byte_decoder(GBK.new_decoder(), bytes)
92    }
93
94    #[cfg(not(feature = "full_encoding"))]
95    {
96        String::from_utf8_lossy(bytes).into_owned()
97    }
98}
99
100#[inline(always)]
101pub(crate) fn decoder_iso2022_jp(bytes: &[u8]) -> String {
102    #[cfg(feature = "full_encoding")]
103    {
104        multi_byte_decoder(ISO_2022_JP.new_decoder(), bytes)
105    }
106
107    #[cfg(not(feature = "full_encoding"))]
108    {
109        String::from_utf8_lossy(bytes).into_owned()
110    }
111}
112
113#[inline(always)]
114pub(crate) fn decoder_windows874(bytes: &[u8]) -> String {
115    #[cfg(feature = "full_encoding")]
116    {
117        multi_byte_decoder(WINDOWS_874.new_decoder(), bytes)
118    }
119
120    #[cfg(not(feature = "full_encoding"))]
121    {
122        String::from_utf8_lossy(bytes).into_owned()
123    }
124}
125
126#[inline(always)]
127pub(crate) fn decoder_ibm866(bytes: &[u8]) -> String {
128    #[cfg(feature = "full_encoding")]
129    {
130        multi_byte_decoder(IBM866.new_decoder(), bytes)
131    }
132
133    #[cfg(not(feature = "full_encoding"))]
134    {
135        String::from_utf8_lossy(bytes).into_owned()
136    }
137}