1use crate::EncodingError;
12use arrayvec::ArrayVec;
13use bitvec::field::BitField;
14use bitvec::order::Lsb0;
15use bitvec::prelude::BitSlice;
16use std::fmt::Display;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
21pub struct PmdChar {
22 pub pmd: u8,
24 pub utf8: char,
26}
27
28impl PmdChar {
29 pub fn from_sequence(seq: &str) -> Result<Self, EncodingError> {
31 let pmd = pmd_seq_to_byte(seq)?;
32
33 let utf8 = match seq.chars().next() {
34 Some('[') => pmd as char,
35 Some(c) => c,
36 _ => unreachable!(), };
38
39 Ok(PmdChar { pmd, utf8 })
40 }
41
42 pub fn to_sequence(&self) -> String {
44 byte_to_pmd_seq(self.pmd).unwrap().to_string()
45 }
46}
47
48impl From<u8> for PmdChar {
50 fn from(value: u8) -> Self {
51 let pmd = byte_to_pmd_seq(value).unwrap();
52 PmdChar::from_sequence(pmd).unwrap()
53 }
54}
55
56#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
60pub struct PmdString(ArrayVec<PmdChar, 10>);
61
62impl PmdString {
63 pub fn new() -> Self {
64 Self(ArrayVec::new())
65 }
66
67 pub fn to_sequence(&self) -> String {
69 self.0.iter().map(|&c| c.to_sequence()).collect()
70 }
71
72 pub fn to_save_bytes(&self) -> [u8; 10] {
74 self.0
75 .iter()
76 .enumerate()
77 .fold([0; 10], |mut result, (i, c)| {
78 result[i] = c.pmd;
79 result
80 })
81 }
82
83 pub fn to_string_until_nul(&self) -> String {
84 self.0
85 .iter()
86 .map_while(|&c| (c.pmd != 0).then_some(c.utf8))
87 .collect()
88 }
89}
90
91impl Display for PmdString {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(f, "{}", self.0.iter().map(|&c| c.utf8).collect::<String>())
96 }
97}
98
99impl Default for PmdString {
100 fn default() -> Self {
101 PmdString::new()
102 }
103}
104
105impl From<&[u8]> for PmdString {
107 fn from(value: &[u8]) -> Self {
108 let mut result = PmdString::new();
109 for &b in value {
110 result.0.push(PmdChar::from(b));
111 }
112
113 result
114 }
115}
116
117impl From<&BitSlice<u8, Lsb0>> for PmdString {
118 fn from(value: &BitSlice<u8, Lsb0>) -> Self {
119 let bytes: u128 = value.load_le();
120 let bytes = bytes.to_le_bytes();
121
122 PmdString::from(&bytes.as_slice()[0..10])
123 }
124}
125
126impl From<PmdString> for Vec<u8> {
130 fn from(value: PmdString) -> Self {
131 value.0.iter().map(|c| c.pmd).collect::<Vec<_>>()
132 }
133}
134
135impl TryFrom<&str> for PmdString {
137 type Error = EncodingError;
138
139 fn try_from(value: &str) -> Result<Self, Self::Error> {
140 let mut result = PmdString::new();
141 let mut chars_iter = value.chars().peekable();
142
143 while let Some(c) = chars_iter.next() {
144 match c {
145 '[' => {
146 let seq: String = chars_iter.by_ref().take_while(|&c| c != ']').collect();
147 let pmd = pmd_seq_to_byte(&format!("[{}]", seq))?;
148 result
149 .0
150 .try_push(PmdChar {
151 utf8: pmd as char,
152 pmd,
153 })
154 .map_err(|_| EncodingError::InvalidPmdStringLen)?;
155 }
156 _ => {
157 let mut buf = [0; 4];
158 let seq = c.encode_utf8(&mut buf);
159 let pmd = pmd_seq_to_byte(seq)?;
160 result
161 .0
162 .try_push(PmdChar { utf8: c, pmd })
163 .map_err(|_| EncodingError::InvalidPmdStringLen)?;
164 }
165 }
166 }
167
168 Ok(result)
169 }
170}
171
172fn pmd_seq_to_byte(s: &str) -> Result<u8, EncodingError> {
173 match s {
174 "[END]" => Ok(0x00),
175 "[$01]" => Ok(0x01),
176 "[$02]" => Ok(0x02),
177 "[$03]" => Ok(0x03),
178 "[$04]" => Ok(0x04),
179 "[$05]" => Ok(0x05),
180 "[$06]" => Ok(0x06),
181 "[$07]" => Ok(0x07),
182 "[$08]" => Ok(0x08),
183 "[$09]" => Ok(0x09),
184 "[$0A]" => Ok(0x0A),
185 "[$0B]" => Ok(0x0B),
186 "[$0C]" => Ok(0x0C),
187 "[$0D]" => Ok(0x0D),
188 "[$0E]" => Ok(0x0E),
189 "[$0F]" => Ok(0x0F),
190 "[$10]" => Ok(0x10),
191 "[$11]" => Ok(0x11),
192 "[$12]" => Ok(0x12),
193 "[$13]" => Ok(0x13),
194 "[$14]" => Ok(0x14),
195 "[$15]" => Ok(0x15),
196 "[$16]" => Ok(0x16),
197 "[$17]" => Ok(0x17),
198 "[$18]" => Ok(0x18),
199 "[$19]" => Ok(0x19),
200 "[$1A]" => Ok(0x1A),
201 "[$1B]" => Ok(0x1B),
202 "[$1C]" => Ok(0x1C),
203 "[$1D]" => Ok(0x1D),
204 "[$1E]" => Ok(0x1E),
205 "[$1F]" => Ok(0x1F),
206 " " => Ok(0x20),
207 "!" => Ok(0x21),
208 "\"" => Ok(0x22),
209 "#" => Ok(0x23),
210 "$" => Ok(0x24),
211 "%" => Ok(0x25),
212 "&" => Ok(0x26),
213 "'" => Ok(0x27),
214 "(" => Ok(0x28),
215 ")" => Ok(0x29),
216 "*" => Ok(0x2A),
217 "+" => Ok(0x2B),
218 "," => Ok(0x2C),
219 "-" => Ok(0x2D),
220 "." => Ok(0x2E),
221 "/" => Ok(0x2F),
222 "0" => Ok(0x30),
223 "1" => Ok(0x31),
224 "2" => Ok(0x32),
225 "3" => Ok(0x33),
226 "4" => Ok(0x34),
227 "5" => Ok(0x35),
228 "6" => Ok(0x36),
229 "7" => Ok(0x37),
230 "8" => Ok(0x38),
231 "9" => Ok(0x39),
232 ":" => Ok(0x3A),
233 ";" => Ok(0x3B),
234 "<" => Ok(0x3C),
235 "=" => Ok(0x3D),
236 ">" => Ok(0x3E),
237 "?" => Ok(0x3F),
238 "@" => Ok(0x40),
239 "A" => Ok(0x41),
240 "B" => Ok(0x42),
241 "C" => Ok(0x43),
242 "D" => Ok(0x44),
243 "E" => Ok(0x45),
244 "F" => Ok(0x46),
245 "G" => Ok(0x47),
246 "H" => Ok(0x48),
247 "I" => Ok(0x49),
248 "J" => Ok(0x4A),
249 "K" => Ok(0x4B),
250 "L" => Ok(0x4C),
251 "M" => Ok(0x4D),
252 "N" => Ok(0x4E),
253 "O" => Ok(0x4F),
254 "P" => Ok(0x50),
255 "Q" => Ok(0x51),
256 "R" => Ok(0x52),
257 "S" => Ok(0x53),
258 "T" => Ok(0x54),
259 "U" => Ok(0x55),
260 "V" => Ok(0x56),
261 "W" => Ok(0x57),
262 "X" => Ok(0x58),
263 "Y" => Ok(0x59),
264 "Z" => Ok(0x5A),
265 "[$5B]" => Ok(0x5B),
266 "\\" => Ok(0x5C),
267 "]" => Ok(0x5D),
268 "^" => Ok(0x5E),
269 "_" => Ok(0x5F),
270 "`" => Ok(0x60),
271 "a" => Ok(0x61),
272 "b" => Ok(0x62),
273 "c" => Ok(0x63),
274 "d" => Ok(0x64),
275 "e" => Ok(0x65),
276 "f" => Ok(0x66),
277 "g" => Ok(0x67),
278 "h" => Ok(0x68),
279 "i" => Ok(0x69),
280 "j" => Ok(0x6A),
281 "k" => Ok(0x6B),
282 "l" => Ok(0x6C),
283 "m" => Ok(0x6D),
284 "n" => Ok(0x6E),
285 "o" => Ok(0x6F),
286 "p" => Ok(0x70),
287 "q" => Ok(0x71),
288 "r" => Ok(0x72),
289 "s" => Ok(0x73),
290 "t" => Ok(0x74),
291 "u" => Ok(0x75),
292 "v" => Ok(0x76),
293 "w" => Ok(0x77),
294 "x" => Ok(0x78),
295 "y" => Ok(0x79),
296 "z" => Ok(0x7A),
297 "{" => Ok(0x7B),
298 "|" => Ok(0x7C),
299 "}" => Ok(0x7D),
300 "[$7E]" => Ok(0x7E),
301 "[$7F]" => Ok(0x7F),
302 "€" => Ok(0x80),
303 "[$81]" => Ok(0x81),
304 "[$82]" => Ok(0x82),
305 "[$83]" => Ok(0x83),
306 "[$84]" => Ok(0x84),
307 "…" => Ok(0x85),
308 "†" => Ok(0x86),
309 "[$87]" => Ok(0x87),
310 "ˆ" => Ok(0x88),
311 "‰" => Ok(0x89),
312 "Š" => Ok(0x8A),
313 "‹" => Ok(0x8B),
314 "Œ" => Ok(0x8C),
315 "[e]" => Ok(0x8D),
316 "Ž" => Ok(0x8E),
317 "[è]" => Ok(0x8F),
318 "‘" => Ok(0x91),
320 "’" => Ok(0x92),
321 "“" => Ok(0x93),
322 "”" => Ok(0x94),
323 "[er]" => Ok(0x96),
325 "[re]" => Ok(0x97),
326 "~" => Ok(0x98),
327 "™" => Ok(0x99),
328 "š" => Ok(0x9A),
329 "›" => Ok(0x9B),
330 "œ" => Ok(0x9C),
331 "•" => Ok(0x9D),
332 "ž" => Ok(0x9E),
333 "Ÿ" => Ok(0x9F),
334 "¡" => Ok(0xA1),
336 "¢" => Ok(0xA2),
337 "£" => Ok(0xA3),
338 "¤" => Ok(0xA4),
339 "¥" => Ok(0xA5),
340 "¦" => Ok(0xA6),
341 "§" => Ok(0xA7),
342 "¨" => Ok(0xA8),
343 "©" => Ok(0xA9),
344 "ª" => Ok(0xAA),
345 "«" => Ok(0xAB),
346 "¬" => Ok(0xAC),
347 "\u{00AD}" => Ok(0xAD),
348 "®" => Ok(0xAE),
349 "¯" => Ok(0xAF),
350 "°" => Ok(0xB0),
351 "±" => Ok(0xB1),
352 "²" => Ok(0xB2),
353 "³" => Ok(0xB3),
354 "´" => Ok(0xB4),
355 "µ" => Ok(0xB5),
356 "¶" => Ok(0xB6),
357 "„" => Ok(0xB7),
358 "‚" => Ok(0xB8),
359 "¹" => Ok(0xB9),
360 "º" => Ok(0xBA),
361 "»" => Ok(0xBB),
362 "←" => Ok(0xBC),
363 "♂" => Ok(0xBD),
364 "♀" => Ok(0xBE),
365 "¿" => Ok(0xBF),
366 "À" => Ok(0xC0),
367 "Á" => Ok(0xC1),
368 "Â" => Ok(0xC2),
369 "Ã" => Ok(0xC3),
370 "Ä" => Ok(0xC4),
371 "Å" => Ok(0xC5),
372 "Æ" => Ok(0xC6),
373 "Ç" => Ok(0xC7),
374 "È" => Ok(0xC8),
375 "É" => Ok(0xC9),
376 "Ê" => Ok(0xCA),
377 "Ë" => Ok(0xCB),
378 "Ì" => Ok(0xCC),
379 "Í" => Ok(0xCD),
380 "Î" => Ok(0xCE),
381 "Ï" => Ok(0xCF),
382 "Ð" => Ok(0xD0),
383 "Ñ" => Ok(0xD1),
384 "Ò" => Ok(0xD2),
385 "Ó" => Ok(0xD3),
386 "Ô" => Ok(0xD4),
387 "Õ" => Ok(0xD5),
388 "Ö" => Ok(0xD6),
389 "×" => Ok(0xD7),
390 "Ø" => Ok(0xD8),
391 "Ù" => Ok(0xD9),
392 "Ú" => Ok(0xDA),
393 "Û" => Ok(0xDB),
394 "Ü" => Ok(0xDC),
395 "Ý" => Ok(0xDD),
396 "Þ" => Ok(0xDE),
397 "ß" => Ok(0xDF),
398 "à" => Ok(0xE0),
399 "á" => Ok(0xE1),
400 "â" => Ok(0xE2),
401 "ã" => Ok(0xE3),
402 "ä" => Ok(0xE4),
403 "å" => Ok(0xE5),
404 "æ" => Ok(0xE6),
405 "ç" => Ok(0xE7),
406 "è" => Ok(0xE8),
407 "é" => Ok(0xE9),
408 "ê" => Ok(0xEA),
409 "ë" => Ok(0xEB),
410 "ì" => Ok(0xEC),
411 "í" => Ok(0xED),
412 "î" => Ok(0xEE),
413 "ï" => Ok(0xEF),
414 "ð" => Ok(0xF0),
415 "ñ" => Ok(0xF1),
416 "ò" => Ok(0xF2),
417 "ó" => Ok(0xF3),
418 "ô" => Ok(0xF4),
419 "õ" => Ok(0xF5),
420 "ö" => Ok(0xF6),
421 "÷" => Ok(0xF7),
422 "ø" => Ok(0xF8),
423 "ù" => Ok(0xF9),
424 "ú" => Ok(0xFA),
425 "û" => Ok(0xFB),
426 "ü" => Ok(0xFC),
427 "ý" => Ok(0xFD),
428 "þ" => Ok(0xFE),
429 "ÿ" => Ok(0xFF),
430 _ => Err(EncodingError::InvalidPmdCharacter(s.to_string())),
431 }
432}
433
434fn byte_to_pmd_seq(byte: u8) -> Result<&'static str, EncodingError> {
435 match byte {
436 0x00 => Ok("[END]"),
437 0x01 => Ok("[$01]"),
438 0x02 => Ok("[$02]"),
439 0x03 => Ok("[$03]"),
440 0x04 => Ok("[$04]"),
441 0x05 => Ok("[$05]"),
442 0x06 => Ok("[$06]"),
443 0x07 => Ok("[$07]"),
444 0x08 => Ok("[$08]"),
445 0x09 => Ok("[$09]"),
446 0x0A => Ok("[$0A]"),
447 0x0B => Ok("[$0B]"),
448 0x0C => Ok("[$0C]"),
449 0x0D => Ok("[$0D]"),
450 0x0E => Ok("[$0E]"),
451 0x0F => Ok("[$0F]"),
452 0x10 => Ok("[$10]"),
453 0x11 => Ok("[$11]"),
454 0x12 => Ok("[$12]"),
455 0x13 => Ok("[$13]"),
456 0x14 => Ok("[$14]"),
457 0x15 => Ok("[$15]"),
458 0x16 => Ok("[$16]"),
459 0x17 => Ok("[$17]"),
460 0x18 => Ok("[$18]"),
461 0x19 => Ok("[$19]"),
462 0x1A => Ok("[$1A]"),
463 0x1B => Ok("[$1B]"),
464 0x1C => Ok("[$1C]"),
465 0x1D => Ok("[$1D]"),
466 0x1E => Ok("[$1E]"),
467 0x1F => Ok("[$1F]"),
468 0x20 => Ok(" "),
469 0x21 => Ok("!"),
470 0x22 => Ok("\""),
471 0x23 => Ok("#"),
472 0x24 => Ok("$"),
473 0x25 => Ok("%"),
474 0x26 => Ok("&"),
475 0x27 => Ok("'"),
476 0x28 => Ok("("),
477 0x29 => Ok(")"),
478 0x2A => Ok("*"),
479 0x2B => Ok("+"),
480 0x2C => Ok(","),
481 0x2D => Ok("-"),
482 0x2E => Ok("."),
483 0x2F => Ok("/"),
484 0x30 => Ok("0"),
485 0x31 => Ok("1"),
486 0x32 => Ok("2"),
487 0x33 => Ok("3"),
488 0x34 => Ok("4"),
489 0x35 => Ok("5"),
490 0x36 => Ok("6"),
491 0x37 => Ok("7"),
492 0x38 => Ok("8"),
493 0x39 => Ok("9"),
494 0x3A => Ok(":"),
495 0x3B => Ok(";"),
496 0x3C => Ok("<"),
497 0x3D => Ok("="),
498 0x3E => Ok(">"),
499 0x3F => Ok("?"),
500 0x40 => Ok("@"),
501 0x41 => Ok("A"),
502 0x42 => Ok("B"),
503 0x43 => Ok("C"),
504 0x44 => Ok("D"),
505 0x45 => Ok("E"),
506 0x46 => Ok("F"),
507 0x47 => Ok("G"),
508 0x48 => Ok("H"),
509 0x49 => Ok("I"),
510 0x4A => Ok("J"),
511 0x4B => Ok("K"),
512 0x4C => Ok("L"),
513 0x4D => Ok("M"),
514 0x4E => Ok("N"),
515 0x4F => Ok("O"),
516 0x50 => Ok("P"),
517 0x51 => Ok("Q"),
518 0x52 => Ok("R"),
519 0x53 => Ok("S"),
520 0x54 => Ok("T"),
521 0x55 => Ok("U"),
522 0x56 => Ok("V"),
523 0x57 => Ok("W"),
524 0x58 => Ok("X"),
525 0x59 => Ok("Y"),
526 0x5A => Ok("Z"),
527 0x5B => Ok("[$5B]"),
528 0x5C => Ok("\\"),
529 0x5D => Ok("]"),
530 0x5E => Ok("^"),
531 0x5F => Ok("_"),
532 0x60 => Ok("`"),
533 0x61 => Ok("a"),
534 0x62 => Ok("b"),
535 0x63 => Ok("c"),
536 0x64 => Ok("d"),
537 0x65 => Ok("e"),
538 0x66 => Ok("f"),
539 0x67 => Ok("g"),
540 0x68 => Ok("h"),
541 0x69 => Ok("i"),
542 0x6A => Ok("j"),
543 0x6B => Ok("k"),
544 0x6C => Ok("l"),
545 0x6D => Ok("m"),
546 0x6E => Ok("n"),
547 0x6F => Ok("o"),
548 0x70 => Ok("p"),
549 0x71 => Ok("q"),
550 0x72 => Ok("r"),
551 0x73 => Ok("s"),
552 0x74 => Ok("t"),
553 0x75 => Ok("u"),
554 0x76 => Ok("v"),
555 0x77 => Ok("w"),
556 0x78 => Ok("x"),
557 0x79 => Ok("y"),
558 0x7A => Ok("z"),
559 0x7B => Ok("{"),
560 0x7C => Ok("|"),
561 0x7D => Ok("}"),
562 0x7E => Ok("[$7E]"),
563 0x7F => Ok("[$7F]"),
564 0x80 => Ok("€"),
565 0x81 => Ok("[$81]"),
566 0x82 => Ok("[$82]"),
567 0x83 => Ok("[$83]"),
568 0x84 => Ok("[$84]"),
569 0x85 => Ok("…"),
570 0x86 => Ok("†"),
571 0x87 => Ok("[$87]"),
572 0x88 => Ok("ˆ"),
573 0x89 => Ok("‰"),
574 0x8A => Ok("Š"),
575 0x8B => Ok("‹"),
576 0x8C => Ok("Œ"),
577 0x8D => Ok("[e]"),
578 0x8E => Ok("Ž"),
579 0x8F => Ok("[è]"),
580 0x90 => Ok("•"),
581 0x91 => Ok("‘"),
582 0x92 => Ok("’"),
583 0x93 => Ok("“"),
584 0x94 => Ok("”"),
585 0x95 => Ok("•"),
586 0x96 => Ok("[er]"),
587 0x97 => Ok("[re]"),
588 0x98 => Ok("~"),
589 0x99 => Ok("™"),
590 0x9A => Ok("š"),
591 0x9B => Ok("›"),
592 0x9C => Ok("œ"),
593 0x9D => Ok("•"),
594 0x9E => Ok("ž"),
595 0x9F => Ok("Ÿ"),
596 0xA0 => Ok(" "),
597 0xA1 => Ok("¡"),
598 0xA2 => Ok("¢"),
599 0xA3 => Ok("£"),
600 0xA4 => Ok("¤"),
601 0xA5 => Ok("¥"),
602 0xA6 => Ok("¦"),
603 0xA7 => Ok("§"),
604 0xA8 => Ok("¨"),
605 0xA9 => Ok("©"),
606 0xAA => Ok("ª"),
607 0xAB => Ok("«"),
608 0xAC => Ok("¬"),
609 0xAD => Ok("\u{00AD}"),
610 0xAE => Ok("®"),
611 0xAF => Ok("¯"),
612 0xB0 => Ok("°"),
613 0xB1 => Ok("±"),
614 0xB2 => Ok("²"),
615 0xB3 => Ok("³"),
616 0xB4 => Ok("´"),
617 0xB5 => Ok("µ"),
618 0xB6 => Ok("¶"),
619 0xB7 => Ok("„"),
620 0xB8 => Ok("‚"),
621 0xB9 => Ok("¹"),
622 0xBA => Ok("º"),
623 0xBB => Ok("»"),
624 0xBC => Ok("←"),
625 0xBD => Ok("♂"),
626 0xBE => Ok("♀"),
627 0xBF => Ok("¿"),
628 0xC0 => Ok("À"),
629 0xC1 => Ok("Á"),
630 0xC2 => Ok("Â"),
631 0xC3 => Ok("Ã"),
632 0xC4 => Ok("Ä"),
633 0xC5 => Ok("Å"),
634 0xC6 => Ok("Æ"),
635 0xC7 => Ok("Ç"),
636 0xC8 => Ok("È"),
637 0xC9 => Ok("É"),
638 0xCA => Ok("Ê"),
639 0xCB => Ok("Ë"),
640 0xCC => Ok("Ì"),
641 0xCD => Ok("Í"),
642 0xCE => Ok("Î"),
643 0xCF => Ok("Ï"),
644 0xD0 => Ok("Ð"),
645 0xD1 => Ok("Ñ"),
646 0xD2 => Ok("Ò"),
647 0xD3 => Ok("Ó"),
648 0xD4 => Ok("Ô"),
649 0xD5 => Ok("Õ"),
650 0xD6 => Ok("Ö"),
651 0xD7 => Ok("×"),
652 0xD8 => Ok("Ø"),
653 0xD9 => Ok("Ù"),
654 0xDA => Ok("Ú"),
655 0xDB => Ok("Û"),
656 0xDC => Ok("Ü"),
657 0xDD => Ok("Ý"),
658 0xDE => Ok("Þ"),
659 0xDF => Ok("ß"),
660 0xE0 => Ok("à"),
661 0xE1 => Ok("á"),
662 0xE2 => Ok("â"),
663 0xE3 => Ok("ã"),
664 0xE4 => Ok("ä"),
665 0xE5 => Ok("å"),
666 0xE6 => Ok("æ"),
667 0xE7 => Ok("ç"),
668 0xE8 => Ok("è"),
669 0xE9 => Ok("é"),
670 0xEA => Ok("ê"),
671 0xEB => Ok("ë"),
672 0xEC => Ok("ì"),
673 0xED => Ok("í"),
674 0xEE => Ok("î"),
675 0xEF => Ok("ï"),
676 0xF0 => Ok("ð"),
677 0xF1 => Ok("ñ"),
678 0xF2 => Ok("ò"),
679 0xF3 => Ok("ó"),
680 0xF4 => Ok("ô"),
681 0xF5 => Ok("õ"),
682 0xF6 => Ok("ö"),
683 0xF7 => Ok("÷"),
684 0xF8 => Ok("ø"),
685 0xF9 => Ok("ù"),
686 0xFA => Ok("ú"),
687 0xFB => Ok("û"),
688 0xFC => Ok("ü"),
689 0xFD => Ok("ý"),
690 0xFE => Ok("þ"),
691 0xFF => Ok("ÿ"),
692 }
693}
694
695#[test]
696fn test_char_round_trip() {
697 let ch = PmdChar::from_sequence("A").unwrap();
698 assert_eq!(ch.utf8, 'A');
699 assert_eq!(ch.pmd, 0x41);
700 let pmd = PmdChar::from(0x41);
701 assert_eq!(ch, pmd);
702}
703
704#[test]
705fn test_char_special_trip() {
706 let ch = PmdChar::from_sequence("[er]").unwrap();
707 assert_eq!(ch.utf8, '\u{96}');
708 assert_eq!(ch.pmd, 0x96);
709 let pmd = PmdChar::from(0x96);
710 assert_eq!(ch, pmd);
711}
712
713#[test]
714#[should_panic]
715
716fn test_char_invalid_sequence() {
717 PmdChar::from_sequence("[LOL]").unwrap();
718}
719
720#[test]
721fn test_char_to_sequence() {
722 let ch = PmdChar::from(0x8D);
723 assert_eq!(ch.to_sequence(), "[e]");
724}
725
726#[test]
727fn test_pmd_string_parse() {
728 let seq = "Oak[END]";
729 PmdString::try_from(seq).unwrap();
730}
731
732#[test]
733#[should_panic]
734fn test_pmd_string_invalid_len() {
735 PmdString::try_from("OakOakOakOak").unwrap();
736}
737
738#[test]
739fn test_pmd_string_to_sequence() {
740 let pmd = PmdString::from([0x00, 0x00, 0x00, 0xC4, 0x88, 0x7E].as_slice());
741 assert_eq!(pmd.to_sequence(), "[END][END][END]Ĉ[$7E]");
742}
743
744#[test]
745fn test_pmd_string_to_string() {
746 let pmd = PmdString::from([0x00, 0x00, 0x00, 0xC4, 0x88, 0x7E].as_slice());
747 assert_eq!(pmd.to_string(), "\0\0\0Ĉ~");
748}
749
750#[test]
751fn test_pmd_string_to_save_bytes() {
752 let pmd = PmdString::from([0x00, 0x00, 0x00, 0xC4, 0x88, 0x7E].as_slice());
753 assert_eq!(
754 pmd.to_save_bytes(),
755 [0x00, 0x00, 0x00, 0xC4, 0x88, 0x7E, 0x00, 0x00, 0x00, 0x00]
756 );
757}
758
759#[test]
760fn test_pmd_string_to_vec() {
761 let pmd = PmdString::from([0xC4, 0x88, 0x7E].as_slice());
762 let vec = Vec::from(pmd);
763
764 assert_eq!(vec.as_slice(), &[0xC4, 0x88, 0x7E]);
765}