bbd_lib/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use lazy_static::lazy_static;
4
5// Braille dot values given in LSB to MSB order for each "style"
6const NLBB: &[u32; 8] = &[8, 16, 32, 128, 1, 2, 4, 64];
7const NLBT: &[u32; 8] = &[128, 32, 16, 8, 64, 4, 2, 1];
8const NRBB: &[u32; 8] = &[1, 2, 4, 64, 8, 16, 32, 128];
9const NRBT: &[u32; 8] = &[64, 4, 2, 1, 128, 32, 16, 8];
10
11// BCD
12const TENS: &[u8] = &[0x00, 0x40, 0x04, 0x44, 0x02, 0x42, 0x06, 0x46, 0x01, 0x41];
13const ONES: &[u8] = &[0x00, 0x80, 0x20, 0xA0, 0x10, 0x90, 0x30, 0xB0, 0x08, 0x88];
14
15lazy_static! {
16    // Encode
17    static ref ENCODE_NLBB: Vec<(u8, u32)> = style_encode(*NLBB);
18    static ref ENCODE_NLBT: Vec<(u8, u32)> = style_encode(*NLBT);
19    static ref ENCODE_NRBB: Vec<(u8, u32)> = style_encode(*NRBB);
20    static ref ENCODE_NRBT: Vec<(u8, u32)> = style_encode(*NRBT);
21
22    // Decode
23    static ref DECODE_NLBB: Vec<(u8, u8)> = style_decode(*NLBB);
24    static ref DECODE_NLBT: Vec<(u8, u8)> = style_decode(*NLBT);
25    static ref DECODE_NRBB: Vec<(u8, u8)> = style_decode(*NRBB);
26    static ref DECODE_NRBT: Vec<(u8, u8)> = style_decode(*NRBT);
27}
28
29pub type EncodeFn = fn(u8) -> char;
30pub type DecodeFn = fn(char) -> u8;
31
32/**
33Translate a [`u8`] to binary representation using the `bcd` encoding
34
35`bcd`: binary coded decimal
36
37Tens | Ones
38---|---
39n/a | 8
4064 | 4
4132 | 2
4216 | 1
43
44```
45use bbd_lib::*;
46
47assert_eq!(
48    (0..=99).map(|x| encode_bcd(x)).collect::<String>(),
49    "\
50        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
51        ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
52    ",
53);
54
55// All byte values greater than 99 panic:
56assert!(
57    (100..=255)
58        .all(|x| std::panic::catch_unwind(|| encode_bcd(x)).is_err()),
59);
60```
61*/
62pub fn encode_bcd(decimal: u8) -> char {
63    if decimal > 99 {
64        panic!("Invalid BCD value: {decimal}! Must be in range `0..=99`.")
65    }
66    let d = decimal as usize;
67    let tens = d / 10;
68    let ones = d - tens * 10;
69    char::from_u32(0x2800 + (TENS[tens] as u32) + (ONES[ones] as u32)).unwrap()
70}
71
72/**
73Translate a binary representation to [`u8`] using the `bcd` encoding
74
75`bcd`: binary coded decimal
76
77Tens | Ones
78---|---
79n/a | 8
8064 | 4
8132 | 2
8216 | 1
83
84```
85use bbd_lib::*;
86
87assert_eq!(
88    "\
89        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
90        ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
91    ".chars().map(|x| decode_bcd(x)).collect::<Vec<u8>>(),
92    (0..=99).collect::<Vec<u8>>(),
93);
94```
95*/
96pub fn decode_bcd(c: char) -> u8 {
97    let b = ((c as u32) - 0x2800) as u8;
98    let mut decimal: usize = 0;
99    for (i, tens) in TENS.iter().enumerate().rev() {
100        if b & *tens == *tens {
101            decimal += i * 10;
102            break;
103        }
104    }
105    for (i, ones) in ONES.iter().enumerate().rev() {
106        if b & *ones == *ones {
107            decimal += i;
108            break;
109        }
110    }
111    decimal as u8
112}
113
114/**
115Translate a [`u8`] to binary representation using the `direct` encoding
116
117Left | Right
118---|---
1191 | 8
1202 | 16
1214 | 32
12264 | 128
123
124```
125use bbd_lib::*;
126
127assert_eq!(
128    (0..=255).map(|x| encode_direct(x)).collect::<String>(),
129    "\
130        ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
131        ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
132        ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
133        ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
134    ",
135);
136```
137*/
138pub fn encode_direct(b: u8) -> char {
139    char::from_u32(0x2800 + (b as u32)).unwrap()
140}
141
142/**
143Translate a binary representation to a [`u8`] using the `direct` encoding
144
145Left | Right
146---|---
1471 | 8
1482 | 16
1494 | 32
15064 | 128
151
152```
153use bbd_lib::*;
154
155assert_eq!(
156    "\
157        ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
158        ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
159        ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
160        ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
161    ".chars().map(|x| decode_direct(x)).collect::<Vec<u8>>(),
162    (0..=255).collect::<Vec<u8>>(),
163);
164*/
165pub fn decode_direct(c: char) -> u8 {
166    ((c as u32) - 0x2800) as u8
167}
168
169/**
170Core of `encode_{nlbb,nlbt,nrbb,nrbt}` functions
171*/
172fn encode_nb(b: u8, values: &[(u8, u32)]) -> char {
173    char::from_u32(values.iter().fold(
174        0x2800,
175        |s, (from, to)| {
176            if b & *from == *from {
177                s + *to
178            } else {
179                s
180            }
181        },
182    ))
183    .unwrap()
184}
185
186/**
187Core of `decode_{nlbb,nlbt,nrbb,nrbt}` functions
188*/
189fn decode_nb(c: char, values: &[(u8, u8)]) -> u8 {
190    let b = ((c as u32) - 0x2800) as u8;
191    values.iter().fold(
192        0,
193        |s, (from, to)| {
194            if b & *from == *from {
195                s + *to
196            } else {
197                s
198            }
199        },
200    )
201}
202
203/**
204Translate a [`u8`] to binary representation using the `nlbb` encoding
205
206`nlbb`: most significant nibble left, most significant bit bottom
207
208Left | Right
209---|---
21016 | 1
21132 | 2
21264 | 4
213128 | 8
214
215```
216use bbd_lib::*;
217
218assert_eq!(
219    (0..=255).map(|x| encode_nlbb(x)).collect::<String>(),
220    "\
221        ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
222        ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
223        ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
224        ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
225    ",
226);
227```
228*/
229pub fn encode_nlbb(b: u8) -> char {
230    encode_nb(b, &ENCODE_NLBB)
231}
232
233/**
234Translate a binary representation to [`u8`] using the `nlbb` encoding
235
236`nlbb`: most significant nibble left, most significant bit bottom
237
238Left | Right
239---|---
24016 | 1
24132 | 2
24264 | 4
243128 | 8
244
245```
246use bbd_lib::*;
247
248assert_eq!(
249    "\
250        ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
251        ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
252        ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
253        ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
254    ".chars().map(|x| decode_nlbb(x)).collect::<Vec<u8>>(),
255    (0..=255).collect::<Vec<u8>>());
256```
257*/
258pub fn decode_nlbb(c: char) -> u8 {
259    decode_nb(c, &DECODE_NLBB)
260}
261
262/**
263Translate a [`u8`] to binary representation using the `nlbt` encoding
264
265`nlbt`: most significant nibble left, most significant bit top
266
267Left | Right
268---|---
269128 | 8
27064 | 4
27132 | 2
27216 | 1
273
274```
275use bbd_lib::*;
276
277assert_eq!(
278    (0..=255).map(|x| encode_nlbt(x)).collect::<String>(),
279    "\
280        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
281        ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
282        ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
283        ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
284    ",
285);
286```
287*/
288pub fn encode_nlbt(b: u8) -> char {
289    encode_nb(b, &ENCODE_NLBT)
290}
291
292/**
293Translate a binary representation to [`u8`] using the `nlbt` encoding
294
295`nlbt`: most significant nibble left, most significant bit top
296
297Left | Right
298---|---
299128 | 8
30064 | 4
30132 | 2
30216 | 1
303
304```
305use bbd_lib::*;
306
307assert_eq!(
308    "\
309        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
310        ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
311        ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
312        ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
313    ".chars().map(|x| decode_nlbt(x)).collect::<Vec<u8>>(),
314    (0..=255).collect::<Vec<u8>>());
315```
316*/
317pub fn decode_nlbt(c: char) -> u8 {
318    decode_nb(c, &DECODE_NLBT)
319}
320
321/**
322Translate a [`u8`] to binary representation using the `nrbb` encoding
323
324`nrbb`: most significant nibble right, most significant bit bottom
325
326Left | Right
327---|---
3281 | 16
3292 | 32
3304 | 64
3318 | 128
332
333```
334use bbd_lib::*;
335
336assert_eq!(
337    (0..=255).map(|x| encode_nrbb(x)).collect::<String>(),
338    "\
339        ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
340        ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
341        ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
342        ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
343    ",
344);
345```
346*/
347pub fn encode_nrbb(b: u8) -> char {
348    encode_nb(b, &ENCODE_NRBB)
349}
350
351/**
352Translate a binary representation to [`u8`] using the `nrbb` encoding
353
354`nrbb`: most significant nibble right, most significant bit bottom
355
356Left | Right
357---|---
3581 | 16
3592 | 32
3604 | 64
3618 | 128
362
363```
364use bbd_lib::*;
365
366assert_eq!(
367    "\
368        ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
369        ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
370        ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
371        ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
372    ".chars().map(|x| decode_nrbb(x)).collect::<Vec<u8>>(),
373    (0..=255).collect::<Vec<u8>>(),
374);
375```
376*/
377pub fn decode_nrbb(c: char) -> u8 {
378    decode_nb(c, &DECODE_NRBB)
379}
380
381/**
382Translate a [`u8`] to binary representation using the `nrbt` encoding
383
384`nrbt`: most significant nibble right, most significant bit top
385
386Left | Right
387---|---
3888 | 128
3894 | 64
3902 | 32
3911 | 16
392
393```
394use bbd_lib::*;
395
396assert_eq!(
397    (0..=255).map(|x| encode_nrbt(x)).collect::<String>(),
398    "\
399        ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
400        ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
401        ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
402        ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
403    ",
404);
405```
406*/
407pub fn encode_nrbt(b: u8) -> char {
408    encode_nb(b, &ENCODE_NRBT)
409}
410
411/**
412Translate a binary representation to [`u8`] using the `nrbt` encoding
413
414`nrbt`: most significant nibble right, most significant bit top
415
416Left | Right
417---|---
4188 | 128
4194 | 64
4202 | 32
4211 | 16
422
423```
424use bbd_lib::*;
425
426assert_eq!(
427    "\
428        ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
429        ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
430        ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
431        ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
432    ".chars().map(|x| decode_nrbt(x)).collect::<Vec<u8>>(),
433    (0..=255).collect::<Vec<u8>>(),
434);
435```
436*/
437pub fn decode_nrbt(c: char) -> u8 {
438    decode_nb(c, &DECODE_NRBT)
439}
440
441/**
442Encode bytes to binary representation using the given function with optional wrapping
443
444```
445use bbd_lib::*;
446
447let bcd_content = (0..=99).collect::<Vec<u8>>();
448let bytes_content = (0..=255).collect::<Vec<u8>>();
449let cases: Vec<(&[u8], EncodeFn, &str)> = vec![
450    (
451        &bcd_content,
452        encode_bcd,
453        "\
454            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
455            ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
456        ",
457    ),
458    (
459        &bytes_content,
460        encode_direct,
461        "\
462            ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
463            ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
464            ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
465            ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
466        ",
467    ),
468    (
469        &bytes_content,
470        encode_nlbb,
471        "\
472            ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
473            ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
474            ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
475            ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
476        ",
477    ),
478    (
479        &bytes_content,
480        encode_nlbt,
481        "\
482            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
483            ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
484            ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
485            ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
486        ",
487    ),
488    (
489        &bytes_content,
490        encode_nrbb,
491        "\
492            ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
493            ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
494            ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
495            ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
496        ",
497    ),
498    (
499        &bytes_content,
500        encode_nrbt,
501        "\
502            ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
503            ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
504            ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
505            ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
506        ",
507    ),
508];
509for (content, convert_byte, result) in cases {
510    assert_eq!(encode(content, convert_byte, 0, 0), result);
511}
512```
513*/
514pub fn encode(
515    content: &[u8],
516    convert_byte: EncodeFn,
517    columns: usize,
518    prev_content_length: usize,
519) -> String {
520    let wrapping = columns > 0;
521    let mut c = if wrapping {
522        prev_content_length - (prev_content_length / columns) * columns
523    } else {
524        0
525    };
526
527    let mut r = String::with_capacity(4 * content.len());
528    for b in content {
529        r.push(convert_byte(*b));
530
531        if wrapping {
532            c += 1;
533            if c >= columns {
534                r.push_str("\\\n");
535                c = 0;
536            }
537        }
538    }
539
540    r
541}
542
543/**
544Decode binary representation to bytes using the given function with optional wrapping
545
546```
547use bbd_lib::*;
548
549let bcd_content = (0..=99).collect::<Vec<u8>>();
550let bytes_content = (0..=255).collect::<Vec<u8>>();
551let cases: Vec<(&str, DecodeFn, &[u8])> = vec![
552    (
553        "\
554            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
555            ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
556        ",
557        decode_bcd,
558        &bcd_content,
559    ),
560    (
561        "\
562            ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
563            ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
564            ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
565            ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
566        ",
567        decode_direct,
568        &bytes_content,
569    ),
570    (
571        "\
572            ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
573            ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
574            ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
575            ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
576        ",
577        decode_nlbb,
578        &bytes_content,
579    ),
580    (
581        "\
582            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
583            ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
584            ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
585            ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
586        ",
587        decode_nlbt,
588        &bytes_content,
589    ),
590    (
591        "\
592            ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
593            ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
594            ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
595            ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
596        ",
597        decode_nrbb,
598        &bytes_content,
599    ),
600    (
601        "\
602            ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
603            ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
604            ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
605            ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
606        ",
607        decode_nrbt,
608        &bytes_content,
609    ),
610];
611for (content, convert_byte, result) in cases {
612    assert_eq!(decode(content, convert_byte), result);
613}
614```
615*/
616pub fn decode(content: &str, convert_char: DecodeFn) -> Vec<u8> {
617    let mut r = Vec::with_capacity(content.len() / 4);
618    for c in content.chars() {
619        if !['\\', '\n'].contains(&c) {
620            r.push(convert_char(c));
621        }
622    }
623    r
624}
625
626/**
627Process a style definition into a list of from/to conversion values for encoding
628*/
629fn style_encode(values: [u32; 8]) -> Vec<(u8, u32)> {
630    values
631        .iter()
632        .cloned()
633        .enumerate()
634        .map(|(i, v)| (1 << i, v))
635        .collect()
636}
637
638/**
639Process a style definition into a list of from/to conversion values for decoding
640*/
641fn style_decode(values: [u32; 8]) -> Vec<(u8, u8)> {
642    values
643        .iter()
644        .cloned()
645        .enumerate()
646        .map(|(i, v)| (v as u8, 1 << i))
647        .collect()
648}