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 { s + *to } else { s }
177        },
178    ))
179    .unwrap()
180}
181
182/**
183Core of `decode_{nlbb,nlbt,nrbb,nrbt}` functions
184*/
185fn decode_nb(c: char, values: &[(u8, u8)]) -> u8 {
186    let b = ((c as u32) - 0x2800) as u8;
187    values.iter().fold(
188        0,
189        |s, (from, to)| {
190            if b & *from == *from { s + *to } else { s }
191        },
192    )
193}
194
195/**
196Translate a [`u8`] to binary representation using the `nlbb` encoding
197
198`nlbb`: most significant nibble left, most significant bit bottom
199
200Left | Right
201---|---
20216 | 1
20332 | 2
20464 | 4
205128 | 8
206
207```
208use bbd_lib::*;
209
210assert_eq!(
211    (0..=255).map(|x| encode_nlbb(x)).collect::<String>(),
212    "\
213        ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
214        ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
215        ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
216        ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
217    ",
218);
219```
220*/
221pub fn encode_nlbb(b: u8) -> char {
222    encode_nb(b, &ENCODE_NLBB)
223}
224
225/**
226Translate a binary representation to [`u8`] using the `nlbb` encoding
227
228`nlbb`: most significant nibble left, most significant bit bottom
229
230Left | Right
231---|---
23216 | 1
23332 | 2
23464 | 4
235128 | 8
236
237```
238use bbd_lib::*;
239
240assert_eq!(
241    "\
242        ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
243        ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
244        ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
245        ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
246    ".chars().map(|x| decode_nlbb(x)).collect::<Vec<u8>>(),
247    (0..=255).collect::<Vec<u8>>());
248```
249*/
250pub fn decode_nlbb(c: char) -> u8 {
251    decode_nb(c, &DECODE_NLBB)
252}
253
254/**
255Translate a [`u8`] to binary representation using the `nlbt` encoding
256
257`nlbt`: most significant nibble left, most significant bit top
258
259Left | Right
260---|---
261128 | 8
26264 | 4
26332 | 2
26416 | 1
265
266```
267use bbd_lib::*;
268
269assert_eq!(
270    (0..=255).map(|x| encode_nlbt(x)).collect::<String>(),
271    "\
272        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
273        ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
274        ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
275        ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
276    ",
277);
278```
279*/
280pub fn encode_nlbt(b: u8) -> char {
281    encode_nb(b, &ENCODE_NLBT)
282}
283
284/**
285Translate a binary representation to [`u8`] using the `nlbt` encoding
286
287`nlbt`: most significant nibble left, most significant bit top
288
289Left | Right
290---|---
291128 | 8
29264 | 4
29332 | 2
29416 | 1
295
296```
297use bbd_lib::*;
298
299assert_eq!(
300    "\
301        ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
302        ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
303        ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
304        ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
305    ".chars().map(|x| decode_nlbt(x)).collect::<Vec<u8>>(),
306    (0..=255).collect::<Vec<u8>>());
307```
308*/
309pub fn decode_nlbt(c: char) -> u8 {
310    decode_nb(c, &DECODE_NLBT)
311}
312
313/**
314Translate a [`u8`] to binary representation using the `nrbb` encoding
315
316`nrbb`: most significant nibble right, most significant bit bottom
317
318Left | Right
319---|---
3201 | 16
3212 | 32
3224 | 64
3238 | 128
324
325```
326use bbd_lib::*;
327
328assert_eq!(
329    (0..=255).map(|x| encode_nrbb(x)).collect::<String>(),
330    "\
331        ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
332        ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
333        ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
334        ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
335    ",
336);
337```
338*/
339pub fn encode_nrbb(b: u8) -> char {
340    encode_nb(b, &ENCODE_NRBB)
341}
342
343/**
344Translate a binary representation to [`u8`] using the `nrbb` encoding
345
346`nrbb`: most significant nibble right, most significant bit bottom
347
348Left | Right
349---|---
3501 | 16
3512 | 32
3524 | 64
3538 | 128
354
355```
356use bbd_lib::*;
357
358assert_eq!(
359    "\
360        ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
361        ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
362        ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
363        ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
364    ".chars().map(|x| decode_nrbb(x)).collect::<Vec<u8>>(),
365    (0..=255).collect::<Vec<u8>>(),
366);
367```
368*/
369pub fn decode_nrbb(c: char) -> u8 {
370    decode_nb(c, &DECODE_NRBB)
371}
372
373/**
374Translate a [`u8`] to binary representation using the `nrbt` encoding
375
376`nrbt`: most significant nibble right, most significant bit top
377
378Left | Right
379---|---
3808 | 128
3814 | 64
3822 | 32
3831 | 16
384
385```
386use bbd_lib::*;
387
388assert_eq!(
389    (0..=255).map(|x| encode_nrbt(x)).collect::<String>(),
390    "\
391        ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
392        ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
393        ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
394        ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
395    ",
396);
397```
398*/
399pub fn encode_nrbt(b: u8) -> char {
400    encode_nb(b, &ENCODE_NRBT)
401}
402
403/**
404Translate a binary representation to [`u8`] using the `nrbt` encoding
405
406`nrbt`: most significant nibble right, most significant bit top
407
408Left | Right
409---|---
4108 | 128
4114 | 64
4122 | 32
4131 | 16
414
415```
416use bbd_lib::*;
417
418assert_eq!(
419    "\
420        ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
421        ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
422        ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
423        ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
424    ".chars().map(|x| decode_nrbt(x)).collect::<Vec<u8>>(),
425    (0..=255).collect::<Vec<u8>>(),
426);
427```
428*/
429pub fn decode_nrbt(c: char) -> u8 {
430    decode_nb(c, &DECODE_NRBT)
431}
432
433/**
434Encode bytes to binary representation using the given function with optional wrapping
435
436```
437use bbd_lib::*;
438
439let bcd_content = (0..=99).collect::<Vec<u8>>();
440let bytes_content = (0..=255).collect::<Vec<u8>>();
441let cases: Vec<(&[u8], EncodeFn, &str)> = vec![
442    (
443        &bcd_content,
444        encode_bcd,
445        "\
446            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
447            ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
448        ",
449    ),
450    (
451        &bytes_content,
452        encode_direct,
453        "\
454            ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
455            ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
456            ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
457            ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
458        ",
459    ),
460    (
461        &bytes_content,
462        encode_nlbb,
463        "\
464            ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
465            ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
466            ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
467            ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
468        ",
469    ),
470    (
471        &bytes_content,
472        encode_nlbt,
473        "\
474            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
475            ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
476            ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
477            ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
478        ",
479    ),
480    (
481        &bytes_content,
482        encode_nrbb,
483        "\
484            ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
485            ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
486            ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
487            ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
488        ",
489    ),
490    (
491        &bytes_content,
492        encode_nrbt,
493        "\
494            ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
495            ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
496            ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
497            ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
498        ",
499    ),
500];
501for (content, convert_byte, result) in cases {
502    assert_eq!(encode(content, convert_byte, 0, 0), result);
503}
504```
505*/
506pub fn encode(
507    content: &[u8],
508    convert_byte: EncodeFn,
509    columns: usize,
510    prev_content_length: usize,
511) -> String {
512    let wrapping = columns > 0;
513    let mut c = if wrapping {
514        prev_content_length - (prev_content_length / columns) * columns
515    } else {
516        0
517    };
518
519    let mut r = String::with_capacity(4 * content.len());
520    for b in content {
521        r.push(convert_byte(*b));
522
523        if wrapping {
524            c += 1;
525            if c >= columns {
526                r.push_str("\\\n");
527                c = 0;
528            }
529        }
530    }
531
532    r
533}
534
535/**
536Decode binary representation to bytes using the given function with optional wrapping
537
538```
539use bbd_lib::*;
540
541let bcd_content = (0..=99).collect::<Vec<u8>>();
542let bytes_content = (0..=255).collect::<Vec<u8>>();
543let cases: Vec<(&str, DecodeFn, &[u8])> = vec![
544    (
545        "\
546            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊\
547            ⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉\
548        ",
549        decode_bcd,
550        &bcd_content,
551    ),
552    (
553        "\
554            ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿\
555            ⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿\
556            ⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿\
557            ⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿\
558        ",
559        decode_direct,
560        &bytes_content,
561    ),
562    (
563        "\
564            ⠀⠈⠐⠘⠠⠨⠰⠸⢀⢈⢐⢘⢠⢨⢰⢸⠁⠉⠑⠙⠡⠩⠱⠹⢁⢉⢑⢙⢡⢩⢱⢹⠂⠊⠒⠚⠢⠪⠲⠺⢂⢊⢒⢚⢢⢪⢲⢺⠃⠋⠓⠛⠣⠫⠳⠻⢃⢋⢓⢛⢣⢫⢳⢻\
565            ⠄⠌⠔⠜⠤⠬⠴⠼⢄⢌⢔⢜⢤⢬⢴⢼⠅⠍⠕⠝⠥⠭⠵⠽⢅⢍⢕⢝⢥⢭⢵⢽⠆⠎⠖⠞⠦⠮⠶⠾⢆⢎⢖⢞⢦⢮⢶⢾⠇⠏⠗⠟⠧⠯⠷⠿⢇⢏⢗⢟⢧⢯⢷⢿\
566            ⡀⡈⡐⡘⡠⡨⡰⡸⣀⣈⣐⣘⣠⣨⣰⣸⡁⡉⡑⡙⡡⡩⡱⡹⣁⣉⣑⣙⣡⣩⣱⣹⡂⡊⡒⡚⡢⡪⡲⡺⣂⣊⣒⣚⣢⣪⣲⣺⡃⡋⡓⡛⡣⡫⡳⡻⣃⣋⣓⣛⣣⣫⣳⣻\
567            ⡄⡌⡔⡜⡤⡬⡴⡼⣄⣌⣔⣜⣤⣬⣴⣼⡅⡍⡕⡝⡥⡭⡵⡽⣅⣍⣕⣝⣥⣭⣵⣽⡆⡎⡖⡞⡦⡮⡶⡾⣆⣎⣖⣞⣦⣮⣶⣾⡇⡏⡗⡟⡧⡯⡷⡿⣇⣏⣗⣟⣧⣯⣷⣿\
568        ",
569        decode_nlbb,
570        &bytes_content,
571    ),
572    (
573        "\
574            ⠀⢀⠠⢠⠐⢐⠰⢰⠈⢈⠨⢨⠘⢘⠸⢸⡀⣀⡠⣠⡐⣐⡰⣰⡈⣈⡨⣨⡘⣘⡸⣸⠄⢄⠤⢤⠔⢔⠴⢴⠌⢌⠬⢬⠜⢜⠼⢼⡄⣄⡤⣤⡔⣔⡴⣴⡌⣌⡬⣬⡜⣜⡼⣼\
575            ⠂⢂⠢⢢⠒⢒⠲⢲⠊⢊⠪⢪⠚⢚⠺⢺⡂⣂⡢⣢⡒⣒⡲⣲⡊⣊⡪⣪⡚⣚⡺⣺⠆⢆⠦⢦⠖⢖⠶⢶⠎⢎⠮⢮⠞⢞⠾⢾⡆⣆⡦⣦⡖⣖⡶⣶⡎⣎⡮⣮⡞⣞⡾⣾\
576            ⠁⢁⠡⢡⠑⢑⠱⢱⠉⢉⠩⢩⠙⢙⠹⢹⡁⣁⡡⣡⡑⣑⡱⣱⡉⣉⡩⣩⡙⣙⡹⣹⠅⢅⠥⢥⠕⢕⠵⢵⠍⢍⠭⢭⠝⢝⠽⢽⡅⣅⡥⣥⡕⣕⡵⣵⡍⣍⡭⣭⡝⣝⡽⣽\
577            ⠃⢃⠣⢣⠓⢓⠳⢳⠋⢋⠫⢫⠛⢛⠻⢻⡃⣃⡣⣣⡓⣓⡳⣳⡋⣋⡫⣫⡛⣛⡻⣻⠇⢇⠧⢧⠗⢗⠷⢷⠏⢏⠯⢯⠟⢟⠿⢿⡇⣇⡧⣧⡗⣗⡷⣷⡏⣏⡯⣯⡟⣟⡿⣿\
578        ",
579        decode_nlbt,
580        &bytes_content,
581    ),
582    (
583        "\
584            ⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟\
585            ⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿\
586            ⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟\
587            ⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿\
588        ",
589        decode_nrbb,
590        &bytes_content,
591    ),
592    (
593        "\
594            ⠀⡀⠄⡄⠂⡂⠆⡆⠁⡁⠅⡅⠃⡃⠇⡇⢀⣀⢄⣄⢂⣂⢆⣆⢁⣁⢅⣅⢃⣃⢇⣇⠠⡠⠤⡤⠢⡢⠦⡦⠡⡡⠥⡥⠣⡣⠧⡧⢠⣠⢤⣤⢢⣢⢦⣦⢡⣡⢥⣥⢣⣣⢧⣧\
595            ⠐⡐⠔⡔⠒⡒⠖⡖⠑⡑⠕⡕⠓⡓⠗⡗⢐⣐⢔⣔⢒⣒⢖⣖⢑⣑⢕⣕⢓⣓⢗⣗⠰⡰⠴⡴⠲⡲⠶⡶⠱⡱⠵⡵⠳⡳⠷⡷⢰⣰⢴⣴⢲⣲⢶⣶⢱⣱⢵⣵⢳⣳⢷⣷\
596            ⠈⡈⠌⡌⠊⡊⠎⡎⠉⡉⠍⡍⠋⡋⠏⡏⢈⣈⢌⣌⢊⣊⢎⣎⢉⣉⢍⣍⢋⣋⢏⣏⠨⡨⠬⡬⠪⡪⠮⡮⠩⡩⠭⡭⠫⡫⠯⡯⢨⣨⢬⣬⢪⣪⢮⣮⢩⣩⢭⣭⢫⣫⢯⣯\
597            ⠘⡘⠜⡜⠚⡚⠞⡞⠙⡙⠝⡝⠛⡛⠟⡟⢘⣘⢜⣜⢚⣚⢞⣞⢙⣙⢝⣝⢛⣛⢟⣟⠸⡸⠼⡼⠺⡺⠾⡾⠹⡹⠽⡽⠻⡻⠿⡿⢸⣸⢼⣼⢺⣺⢾⣾⢹⣹⢽⣽⢻⣻⢿⣿\
598        ",
599        decode_nrbt,
600        &bytes_content,
601    ),
602];
603for (content, convert_byte, result) in cases {
604    assert_eq!(decode(content, convert_byte), result);
605}
606```
607*/
608pub fn decode(content: &str, convert_char: DecodeFn) -> Vec<u8> {
609    let mut r = Vec::with_capacity(content.len() / 4);
610    for c in content.chars() {
611        if !['\\', '\n'].contains(&c) {
612            r.push(convert_char(c));
613        }
614    }
615    r
616}
617
618/**
619Process a style definition into a list of from/to conversion values for encoding
620*/
621fn style_encode(values: [u32; 8]) -> Vec<(u8, u32)> {
622    values
623        .iter()
624        .cloned()
625        .enumerate()
626        .map(|(i, v)| (1 << i, v))
627        .collect()
628}
629
630/**
631Process a style definition into a list of from/to conversion values for decoding
632*/
633fn style_decode(values: [u32; 8]) -> Vec<(u8, u8)> {
634    values
635        .iter()
636        .cloned()
637        .enumerate()
638        .map(|(i, v)| (v as u8, 1 << i))
639        .collect()
640}