1#![cfg_attr(not(test), no_std)]
2
3pub struct Encoder<I, F>
5where
6 I: Iterator<Item = u8>,
7 F: Fn(u8) -> char,
8{
9 iterator: I,
10 encode: F,
11}
12
13impl<I, F> Encoder<I, F>
14where
15 I: Iterator<Item = u8>,
16 F: Fn(u8) -> char,
17{
18 pub fn new(iterator: I, encode: F) -> Self {
19 Self { iterator, encode }
20 }
21}
22
23impl<I, F> Iterator for Encoder<I, F>
24where
25 I: Iterator<Item = u8>,
26 F: Fn(u8) -> char,
27{
28 type Item = char;
29
30 fn next(&mut self) -> Option<Self::Item> {
31 self.iterator.next().map(|byte| (self.encode)(byte))
32 }
33}
34
35pub struct Decoder<I, F>
38where
39 I: Iterator<Item = char>,
40 F: Fn(char) -> Option<u8>,
41{
42 iterator: I,
43 decode: F,
44}
45
46impl<I, F> Decoder<I, F>
47where
48 I: Iterator<Item = char>,
49 F: Fn(char) -> Option<u8>,
50{
51 pub fn new(iterator: I, decode: F) -> Self {
52 Self { iterator, decode }
53 }
54}
55
56impl<I, F> Iterator for Decoder<I, F>
57where
58 I: Iterator<Item = char>,
59 F: Fn(char) -> Option<u8>,
60{
61 type Item = Option<u8>;
62
63 fn next(&mut self) -> Option<Self::Item> {
64 self.iterator.next().map(|byte| (self.decode)(byte))
65 }
66}
67
68pub fn encode_basic(byte: u8) -> char {
70 byte as char
71}
72
73pub fn decode_basic(c: char) -> Option<u8> {
75 c.try_into().ok()
76}
77
78pub fn encode_papu(byte: u8) -> char {
85 match byte {
86 b @ 0x00..=0x1F => (b + 0xB0) as char,
87 b @ 0x20..=0x7E => b as char,
88 0x7F => '§',
89 b @ (0x80..=0xC8 | 0xCA..) => unsafe { char::from_u32_unchecked(b as u32 + 0x80) },
91 0xC9 => '¤',
92 }
93}
94
95pub const fn decode_papu(c: char) -> Option<u8> {
98 Some(match c as u32 {
99 b @ 0xB0..=0xCF => (b - 0xB0) as u8,
100 b @ 0x20..=0x7E => b as u8,
101 0xA7 => 0x7F,
102 b @ (0x100..=0x148 | 0x14A..=0x17F) => (b - 0x80) as u8,
103 0xA4 => 0xC9,
104 _ => return None,
105 })
106}
107
108pub fn encode_tpapu(byte: u8) -> char {
115 match byte {
116 b @ 0x00..=0x0B => (b + 0xA1) as char,
117 b @ 0x0C..=0x1F => (b + (0xAE - 0x0C)) as char,
118 b @ 0x20..=0x7E => b as char,
119 b @ 0x7F..=0xFF => unsafe { char::from_u32_unchecked(b as u32 + (0xC2 - 0x7F)) },
120 }
121}
122
123pub fn decode_tpapu(c: char) -> Option<u8> {
125 Some(match c as u32 {
126 b @ 0xA1..=0xAC => (b - 0xA1) as u8,
127 b @ 0xAE..=0xC1 => (b - (0xAE - 0x0C)) as u8,
128 b @ 0x20..=0x7E => b as u8,
129 b @ 0xC2..=0x142 => (b - (0xC2 - 0x7F)) as u8,
130 _ => return None,
131 })
132}
133
134pub fn encode_emoji(byte: u8) -> char {
140 match byte {
141 b @ 0x00..=0x4F => unsafe { char::from_u32_unchecked(b as u32 + 0x1F330) },
142 b @ 0x50..=0x8F => unsafe { char::from_u32_unchecked(b as u32 + (0x1F400 - 0x50)) },
143 b @ 0x90..=0xDF => unsafe { char::from_u32_unchecked(b as u32 + (0x1F600 - 0x90)) },
144 b @ 0xE0..=0xFF => unsafe { char::from_u32_unchecked(b as u32 + (0x1F910 - 0xE0)) },
145 }
146}
147
148pub const fn decode_emoji(c: char) -> Option<u8> {
151 Some(match c as u32 {
152 b @ 0x1F330..=0x1F37F => (b - 0x1F330) as u8,
153 b @ 0x1F400..=0x1F43F => (b - (0x1F400 - 0x50)) as u8,
154 b @ 0x1F600..=0x1F64F => (b - (0x1F600 - 0x90)) as u8,
155 b @ 0x1F910..=0x1F92F => (b - (0x1F910 - 0xE0)) as u8,
156 _ => return None,
157 })
158}
159
160pub trait Encode: Iterator<Item = u8>
161where
162 Self: Sized,
163{
164 fn base256u<F>(self, function: F) -> Encoder<Self, F>
165 where
166 F: Fn(u8) -> char,
167 {
168 Encoder::new(self, function)
169 }
170
171 fn base256u_basic(self) -> Encoder<Self, fn(u8) -> char> {
172 self.base256u(encode_basic)
173 }
174 fn base256u_papu(self) -> Encoder<Self, fn(u8) -> char> {
175 self.base256u(encode_papu)
176 }
177 fn base256u_tpapu(self) -> Encoder<Self, fn(u8) -> char> {
178 self.base256u(encode_tpapu)
179 }
180 fn base256u_emoji(self) -> Encoder<Self, fn(u8) -> char> {
181 self.base256u(encode_emoji)
182 }
183}
184
185impl<T> Encode for T where T: Iterator<Item = u8> {}
186
187pub trait Decode: Iterator<Item = char>
188where
189 Self: Sized,
190{
191 fn base256u<F>(self, function: F) -> Decoder<Self, F>
192 where
193 F: Fn(char) -> Option<u8>,
194 {
195 Decoder::new(self, function)
196 }
197
198 fn base256u_basic(self) -> Decoder<Self, fn(char) -> Option<u8>> {
199 self.base256u(decode_basic)
200 }
201 fn base256u_papu(self) -> Decoder<Self, fn(char) -> Option<u8>> {
202 self.base256u(decode_papu)
203 }
204 fn base256u_tpapu(self) -> Decoder<Self, fn(char) -> Option<u8>> {
205 self.base256u(decode_tpapu)
206 }
207 fn base256u_emoji(self) -> Decoder<Self, fn(char) -> Option<u8>> {
208 self.base256u(decode_emoji)
209 }
210}
211
212impl<T> Decode for T where T: Iterator<Item = char> {}
213
214#[cfg(test)]
215mod tests {
216 use crate::{Decode, Encode};
217
218 #[test]
219 fn encoding_basic() {
220 let encoded: String = (u8::MIN..=u8::MAX).base256u_basic().collect();
221 assert_eq!(encoded, "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\u{9}\u{A}\u{B}\u{C}\u{D}\u{E}\u{F}\u{10}\u{11}\u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1A}\u{1B}\u{1C}\u{1D}\u{1E}\u{1F}\u{20}\u{21}\u{22}\u{23}\u{24}\u{25}\u{26}\u{27}\u{28}\u{29}\u{2A}\u{2B}\u{2C}\u{2D}\u{2E}\u{2F}\u{30}\u{31}\u{32}\u{33}\u{34}\u{35}\u{36}\u{37}\u{38}\u{39}\u{3A}\u{3B}\u{3C}\u{3D}\u{3E}\u{3F}\u{40}\u{41}\u{42}\u{43}\u{44}\u{45}\u{46}\u{47}\u{48}\u{49}\u{4A}\u{4B}\u{4C}\u{4D}\u{4E}\u{4F}\u{50}\u{51}\u{52}\u{53}\u{54}\u{55}\u{56}\u{57}\u{58}\u{59}\u{5A}\u{5B}\u{5C}\u{5D}\u{5E}\u{5F}\u{60}\u{61}\u{62}\u{63}\u{64}\u{65}\u{66}\u{67}\u{68}\u{69}\u{6A}\u{6B}\u{6C}\u{6D}\u{6E}\u{6F}\u{70}\u{71}\u{72}\u{73}\u{74}\u{75}\u{76}\u{77}\u{78}\u{79}\u{7A}\u{7B}\u{7C}\u{7D}\u{7E}\u{7F}\u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8A}\u{8B}\u{8C}\u{8D}\u{8E}\u{8F}\u{90}\u{91}\u{92}\u{93}\u{94}\u{95}\u{96}\u{97}\u{98}\u{99}\u{9A}\u{9B}\u{9C}\u{9D}\u{9E}\u{9F}\u{A0}\u{A1}\u{A2}\u{A3}\u{A4}\u{A5}\u{A6}\u{A7}\u{A8}\u{A9}\u{AA}\u{AB}\u{AC}\u{AD}\u{AE}\u{AF}\u{B0}\u{B1}\u{B2}\u{B3}\u{B4}\u{B5}\u{B6}\u{B7}\u{B8}\u{B9}\u{BA}\u{BB}\u{BC}\u{BD}\u{BE}\u{BF}\u{C0}\u{C1}\u{C2}\u{C3}\u{C4}\u{C5}\u{C6}\u{C7}\u{C8}\u{C9}\u{CA}\u{CB}\u{CC}\u{CD}\u{CE}\u{CF}\u{D0}\u{D1}\u{D2}\u{D3}\u{D4}\u{D5}\u{D6}\u{D7}\u{D8}\u{D9}\u{DA}\u{DB}\u{DC}\u{DD}\u{DE}\u{DF}\u{E0}\u{E1}\u{E2}\u{E3}\u{E4}\u{E5}\u{E6}\u{E7}\u{E8}\u{E9}\u{EA}\u{EB}\u{EC}\u{ED}\u{EE}\u{EF}\u{F0}\u{F1}\u{F2}\u{F3}\u{F4}\u{F5}\u{F6}\u{F7}\u{F8}\u{F9}\u{FA}\u{FB}\u{FC}\u{FD}\u{FE}\u{FF}");
222 let encoded: String = b"Pack my box with five dozen liquor jugs."
223 .into_iter()
224 .copied()
225 .base256u_basic()
226 .collect();
227 assert_eq!(encoded, "Pack my box with five dozen liquor jugs.");
228 }
229
230 #[test]
231 fn decoding_basic() {
232 let decoded: Vec<Option<u8>> = "\u{0}\u{1}\u{2}\u{3}\u{4}\u{5}\u{6}\u{7}\u{8}\u{9}\u{A}\u{B}\u{C}\u{D}\u{E}\u{F}\u{10}\u{11}\u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\u{1A}\u{1B}\u{1C}\u{1D}\u{1E}\u{1F}\u{20}\u{21}\u{22}\u{23}\u{24}\u{25}\u{26}\u{27}\u{28}\u{29}\u{2A}\u{2B}\u{2C}\u{2D}\u{2E}\u{2F}\u{30}\u{31}\u{32}\u{33}\u{34}\u{35}\u{36}\u{37}\u{38}\u{39}\u{3A}\u{3B}\u{3C}\u{3D}\u{3E}\u{3F}\u{40}\u{41}\u{42}\u{43}\u{44}\u{45}\u{46}\u{47}\u{48}\u{49}\u{4A}\u{4B}\u{4C}\u{4D}\u{4E}\u{4F}\u{50}\u{51}\u{52}\u{53}\u{54}\u{55}\u{56}\u{57}\u{58}\u{59}\u{5A}\u{5B}\u{5C}\u{5D}\u{5E}\u{5F}\u{60}\u{61}\u{62}\u{63}\u{64}\u{65}\u{66}\u{67}\u{68}\u{69}\u{6A}\u{6B}\u{6C}\u{6D}\u{6E}\u{6F}\u{70}\u{71}\u{72}\u{73}\u{74}\u{75}\u{76}\u{77}\u{78}\u{79}\u{7A}\u{7B}\u{7C}\u{7D}\u{7E}\u{7F}\u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8A}\u{8B}\u{8C}\u{8D}\u{8E}\u{8F}\u{90}\u{91}\u{92}\u{93}\u{94}\u{95}\u{96}\u{97}\u{98}\u{99}\u{9A}\u{9B}\u{9C}\u{9D}\u{9E}\u{9F}\u{A0}\u{A1}\u{A2}\u{A3}\u{A4}\u{A5}\u{A6}\u{A7}\u{A8}\u{A9}\u{AA}\u{AB}\u{AC}\u{AD}\u{AE}\u{AF}\u{B0}\u{B1}\u{B2}\u{B3}\u{B4}\u{B5}\u{B6}\u{B7}\u{B8}\u{B9}\u{BA}\u{BB}\u{BC}\u{BD}\u{BE}\u{BF}\u{C0}\u{C1}\u{C2}\u{C3}\u{C4}\u{C5}\u{C6}\u{C7}\u{C8}\u{C9}\u{CA}\u{CB}\u{CC}\u{CD}\u{CE}\u{CF}\u{D0}\u{D1}\u{D2}\u{D3}\u{D4}\u{D5}\u{D6}\u{D7}\u{D8}\u{D9}\u{DA}\u{DB}\u{DC}\u{DD}\u{DE}\u{DF}\u{E0}\u{E1}\u{E2}\u{E3}\u{E4}\u{E5}\u{E6}\u{E7}\u{E8}\u{E9}\u{EA}\u{EB}\u{EC}\u{ED}\u{EE}\u{EF}\u{F0}\u{F1}\u{F2}\u{F3}\u{F4}\u{F5}\u{F6}\u{F7}\u{F8}\u{F9}\u{FA}\u{FB}\u{FC}\u{FD}\u{FE}\u{FF}Ɲʼn".chars().base256u_basic().collect();
233 let mut matcher: Vec<Option<u8>> = (u8::MIN..=u8::MAX).map(|b| Some(b)).collect();
234 matcher.push(None);
235 matcher.push(None);
236 assert_eq!(decoded, matcher);
237 let decoded: Vec<u8> = "Pack my box with five dozen liquor jugs."
238 .chars()
239 .base256u_basic()
240 .map(|c| c.unwrap())
241 .collect();
242 assert_eq!(
243 decoded.as_slice(),
244 b"Pack my box with five dozen liquor jugs."
245 );
246 }
247 #[test]
248 fn encoding_papu() {
249 let encoded: String = (u8::MIN..=u8::MAX).base256u_papu().collect();
250 assert_eq!(encoded, "°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~§ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇň¤ŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ");
251 let encoded: String = b"Pack my box with five dozen liquor jugs."
252 .into_iter()
253 .copied()
254 .base256u_papu()
255 .collect();
256 assert_eq!(encoded, "Pack my box with five dozen liquor jugs.");
257 }
258
259 #[test]
260 fn decoding_papu() {
261 let decoded: Vec<Option<u8>> = "°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~§ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇň¤ŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƝʼn".chars().base256u_papu().collect();
262 let mut matcher: Vec<Option<u8>> = (u8::MIN..=u8::MAX).map(|b| Some(b)).collect();
263 matcher.push(None);
264 matcher.push(None);
265 assert_eq!(decoded, matcher);
266 let decoded: Vec<u8> = "Pack my box with five dozen liquor jugs."
267 .chars()
268 .base256u_papu()
269 .map(|c| c.unwrap())
270 .collect();
271 assert_eq!(
272 decoded.as_slice(),
273 b"Pack my box with five dozen liquor jugs."
274 );
275 }
276
277 #[test]
278 fn encoding_tpapu() {
279 let encoded: String = (u8::MIN..=u8::MAX).base256u_tpapu().collect();
280 assert_eq!(encoded, "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁł");
281 let encoded: String = b"Pack my box with five dozen liquor jugs."
282 .into_iter()
283 .copied()
284 .base256u_tpapu()
285 .collect();
286 assert_eq!(encoded, "Pack my box with five dozen liquor jugs.");
287 }
288
289 #[test]
290 fn decoding_tpapu() {
291 let decoded: Vec<Option<u8>> = "¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłƝʼn".chars().base256u_tpapu().collect();
292 let mut matcher: Vec<Option<u8>> = (u8::MIN..=u8::MAX).map(|b| Some(b)).collect();
293 matcher.push(None);
294 matcher.push(None);
295 assert_eq!(decoded, matcher);
296 let decoded: Vec<u8> = "Pack my box with five dozen liquor jugs."
297 .chars()
298 .base256u_tpapu()
299 .map(|c| c.unwrap())
300 .collect();
301 assert_eq!(
302 decoded.as_slice(),
303 b"Pack my box with five dozen liquor jugs."
304 );
305 }
306 #[test]
307 fn encoding_emoji() {
308 let encoded: String = (u8::MIN..=u8::MAX).base256u_emoji().collect();
309 assert_eq!(encoded, "🌰🌱🌲🌳🌴🌵🌶🌷🌸🌹🌺🌻🌼🌽🌾🌿🍀🍁🍂🍃🍄🍅🍆🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍔🍕🍖🍗🍘🍙🍚🍛🍜🍝🍞🍟🍠🍡🍢🍣🍤🍥🍦🍧🍨🍩🍪🍫🍬🍭🍮🍯🍰🍱🍲🍳🍴🍵🍶🍷🍸🍹🍺🍻🍼🍽🍾🍿🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮😯😰😱😲😳😴😵😶😷😸😹😺😻😼😽😾😿🙀🙁🙂🙃🙄🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯");
310 let encoded: String = b"Pack my box with five dozen liquor jugs."
311 .into_iter()
312 .copied()
313 .base256u_emoji()
314 .collect();
315 assert_eq!(
316 encoded,
317 "🐀🐑🐓🐛🍐🐝🐩🍐🐒🐟🐨🍐🐧🐙🐤🐘🍐🐖🐙🐦🐕🍐🐔🐟🐪🐕🐞🍐🐜🐙🐡🐥🐟🐢🍐🐚🐥🐗🐣🍞"
318 );
319 }
320 #[test]
321 fn decoding_emoji() {
322 let decoded: Vec<Option<u8>> = "🌰🌱🌲🌳🌴🌵🌶🌷🌸🌹🌺🌻🌼🌽🌾🌿🍀🍁🍂🍃🍄🍅🍆🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍔🍕🍖🍗🍘🍙🍚🍛🍜🍝🍞🍟🍠🍡🍢🍣🍤🍥🍦🍧🍨🍩🍪🍫🍬🍭🍮🍯🍰🍱🍲🍳🍴🍵🍶🍷🍸🍹🍺🍻🍼🍽🍾🍿🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮😯😰😱😲😳😴😵😶😷😸😹😺😻😼😽😾😿🙀🙁🙂🙃🙄🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯Ɲʼn".chars().base256u_emoji().collect();
323 let mut matcher: Vec<Option<u8>> = (u8::MIN..=u8::MAX).map(|b| Some(b)).collect();
324 matcher.push(None);
325 matcher.push(None);
326 assert_eq!(decoded, matcher);
327 let decoded: Vec<u8> =
328 "🐀🐑🐓🐛🍐🐝🐩🍐🐒🐟🐨🍐🐧🐙🐤🐘🍐🐖🐙🐦🐕🍐🐔🐟🐪🐕🐞🍐🐜🐙🐡🐥🐟🐢🍐🐚🐥🐗🐣🍞"
329 .chars()
330 .base256u_emoji()
331 .map(|c| c.unwrap())
332 .collect();
333 assert_eq!(
334 decoded.as_slice(),
335 b"Pack my box with five dozen liquor jugs."
336 );
337 }
338}