1use ibig::UBig;
2use num_traits::{Pow, Zero};
3use once_cell::sync::Lazy;
4use std::{cmp::PartialEq, collections::HashMap, ops::Rem};
5
6use super::ob::{fein, fynd};
7
8#[derive(thiserror::Error, Debug, Clone)]
10pub enum Error {
11 #[error("Value must begin with leader: {0}")]
12 LeaderMissing(String),
13 #[error("Invalid prefix value: {0}")]
14 InvalidPrefix(String),
15 #[error("Invalid suffix value: {0}")]
16 InvalidSuffix(String),
17 #[error("Invalid section: {0}")]
18 InvalidSection(String),
19 #[error("Full six-letter words required")]
20 ZeroPadRequired,
21 #[error("Invalid hex string: {0}")]
22 InvalidHex(String),
23 #[error("Invalid decimal string: {0}")]
24 InvalidDecimal(String),
25 #[error("Invalid separator")]
26 InvalidSeparator,
27 #[error("Integer value out of bounds")]
28 OutOfBounds,
29}
30
31pub const PREFIXES: [&'static str; 256] = [
33 "doz", "mar", "bin", "wan", "sam", "lit", "sig", "hid", "fid", "lis", "sog", "dir", "wac",
34 "sab", "wis", "sib", "rig", "sol", "dop", "mod", "fog", "lid", "hop", "dar", "dor", "lor",
35 "hod", "fol", "rin", "tog", "sil", "mir", "hol", "pas", "lac", "rov", "liv", "dal", "sat",
36 "lib", "tab", "han", "tic", "pid", "tor", "bol", "fos", "dot", "los", "dil", "for", "pil",
37 "ram", "tir", "win", "tad", "bic", "dif", "roc", "wid", "bis", "das", "mid", "lop", "ril",
38 "nar", "dap", "mol", "san", "loc", "nov", "sit", "nid", "tip", "sic", "rop", "wit", "nat",
39 "pan", "min", "rit", "pod", "mot", "tam", "tol", "sav", "pos", "nap", "nop", "som", "fin",
40 "fon", "ban", "mor", "wor", "sip", "ron", "nor", "bot", "wic", "soc", "wat", "dol", "mag",
41 "pic", "dav", "bid", "bal", "tim", "tas", "mal", "lig", "siv", "tag", "pad", "sal", "div",
42 "dac", "tan", "sid", "fab", "tar", "mon", "ran", "nis", "wol", "mis", "pal", "las", "dis",
43 "map", "rab", "tob", "rol", "lat", "lon", "nod", "nav", "fig", "nom", "nib", "pag", "sop",
44 "ral", "bil", "had", "doc", "rid", "moc", "pac", "rav", "rip", "fal", "tod", "til", "tin",
45 "hap", "mic", "fan", "pat", "tac", "lab", "mog", "sim", "son", "pin", "lom", "ric", "tap",
46 "fir", "has", "bos", "bat", "poc", "hac", "tid", "hav", "sap", "lin", "dib", "hos", "dab",
47 "bit", "bar", "rac", "par", "lod", "dos", "bor", "toc", "hil", "mac", "tom", "dig", "fil",
48 "fas", "mit", "hob", "har", "mig", "hin", "rad", "mas", "hal", "rag", "lag", "fad", "top",
49 "mop", "hab", "nil", "nos", "mil", "fop", "fam", "dat", "nol", "din", "hat", "nac", "ris",
50 "fot", "rib", "hoc", "nim", "lar", "fit", "wal", "rap", "sar", "nal", "mos", "lan", "don",
51 "dan", "lad", "dov", "riv", "bac", "pol", "lap", "tal", "pit", "nam", "bon", "ros", "ton",
52 "fod", "pon", "sov", "noc", "sor", "lav", "mat", "mip", "fip",
53];
54
55pub const SUFFIXES: [&'static str; 256] = [
57 "zod", "nec", "bud", "wes", "sev", "per", "sut", "let", "ful", "pen", "syt", "dur", "wep",
58 "ser", "wyl", "sun", "ryp", "syx", "dyr", "nup", "heb", "peg", "lup", "dep", "dys", "put",
59 "lug", "hec", "ryt", "tyv", "syd", "nex", "lun", "mep", "lut", "sep", "pes", "del", "sul",
60 "ped", "tem", "led", "tul", "met", "wen", "byn", "hex", "feb", "pyl", "dul", "het", "mev",
61 "rut", "tyl", "wyd", "tep", "bes", "dex", "sef", "wyc", "bur", "der", "nep", "pur", "rys",
62 "reb", "den", "nut", "sub", "pet", "rul", "syn", "reg", "tyd", "sup", "sem", "wyn", "rec",
63 "meg", "net", "sec", "mul", "nym", "tev", "web", "sum", "mut", "nyx", "rex", "teb", "fus",
64 "hep", "ben", "mus", "wyx", "sym", "sel", "ruc", "dec", "wex", "syr", "wet", "dyl", "myn",
65 "mes", "det", "bet", "bel", "tux", "tug", "myr", "pel", "syp", "ter", "meb", "set", "dut",
66 "deg", "tex", "sur", "fel", "tud", "nux", "rux", "ren", "wyt", "nub", "med", "lyt", "dus",
67 "neb", "rum", "tyn", "seg", "lyx", "pun", "res", "red", "fun", "rev", "ref", "mec", "ted",
68 "rus", "bex", "leb", "dux", "ryn", "num", "pyx", "ryg", "ryx", "fep", "tyr", "tus", "tyc",
69 "leg", "nem", "fer", "mer", "ten", "lus", "nus", "syl", "tec", "mex", "pub", "rym", "tuc",
70 "fyl", "lep", "deb", "ber", "mug", "hut", "tun", "byl", "sud", "pem", "dev", "lur", "def",
71 "bus", "bep", "run", "mel", "pex", "dyt", "byt", "typ", "lev", "myl", "wed", "duc", "fur",
72 "fex", "nul", "luc", "len", "ner", "lex", "rup", "ned", "lec", "ryd", "lyd", "fen", "wel",
73 "nyd", "hus", "rel", "rud", "nes", "hes", "fet", "des", "ret", "dun", "ler", "nyr", "seb",
74 "hul", "ryl", "lud", "rem", "lys", "fyn", "wer", "ryc", "sug", "nys", "nyl", "lyn", "dyn",
75 "dem", "lux", "fed", "sed", "bec", "mun", "lyr", "tes", "mud", "nyt", "byr", "sen", "weg",
76 "fyr", "mur", "tel", "rep", "teg", "pec", "nel", "nev", "fes",
77];
78
79pub static PREFIX_VALUES: Lazy<HashMap<&'static str, u8>> = Lazy::new(|| {
81 let mut h = HashMap::with_capacity(256);
82 for (index, value) in PREFIXES.iter().enumerate() {
83 h.insert(*value, index as u8);
84 }
85 h
86});
87
88pub static SUFFIX_VALUES: Lazy<HashMap<&'static str, u8>> = Lazy::new(|| {
90 let mut h = HashMap::with_capacity(256);
91 for (index, value) in SUFFIXES.iter().enumerate() {
92 h.insert(*value, index as u8);
93 }
94 h
95});
96
97pub fn static_pre(pre: &str) -> Result<&'static str, Error> {
99 PREFIX_VALUES
100 .get_key_value(pre)
101 .ok_or(Error::InvalidPrefix(pre.to_string()))
102 .map(|(k, _)| *k)
103}
104
105pub fn static_suf(suf: &str) -> Result<&'static str, Error> {
107 SUFFIX_VALUES
108 .get_key_value(suf)
109 .ok_or(Error::InvalidSuffix(suf.to_string()))
110 .map(|(k, _)| *k)
111}
112
113pub fn prefix_value(pre: &str) -> Result<u8, Error> {
115 PREFIX_VALUES
116 .get(pre)
117 .ok_or(Error::InvalidPrefix(pre.to_string()))
118 .map(|v| *v)
119}
120
121pub fn suffix_value(suf: &str) -> Result<u8, Error> {
123 SUFFIX_VALUES
124 .get(suf)
125 .ok_or(Error::InvalidSuffix(suf.to_string()))
126 .map(|v| *v)
127}
128
129fn met(a: usize, b: &UBig) -> usize {
130 let zero = UBig::zero();
131 let mut b = b.clone();
132 let mut c = 0;
133 loop {
134 if b.eq(&zero) {
135 return c;
136 }
137 b = b >> 2.pow(a) as usize;
138 c = c + 1;
139 }
140}
141
142fn end(a: usize, c: &UBig) -> UBig {
143 c.rem(UBig::from(2u64.pow(2u32.pow(a as u32))))
144}
145
146pub fn patq<T>(n: T) -> String
148where
149 UBig: From<T>,
150{
151 big2patq(&UBig::from(n))
152}
153
154pub fn big2patq(n: &UBig) -> String {
156 let buf = if n.is_zero() {
157 vec![0]
158 } else {
159 n.to_be_bytes()
160 };
161 buf2patq(&buf)
162}
163
164pub fn patp<T>(n: T) -> String
166where
167 UBig: From<T>,
168{
169 big2patp(&UBig::from(n))
170}
171
172pub fn big2patp(n: &UBig) -> String {
174 let n = fein(n);
175 let buf = if n.is_zero() {
176 vec![0]
177 } else {
178 n.to_be_bytes()
179 };
180 buf2patp(&buf)
181}
182
183pub fn buf2patq(buf: &[u8]) -> String {
185 buf2pat(buf, ".~", false, false)
186}
187
188pub fn buf2patp(buf: &[u8]) -> String {
190 buf2pat(buf, "~", true, true)
191}
192
193pub fn buf2pat(buf: &[u8], leader: &str, zero_pad: bool, quad_sep: bool) -> String {
195 let zero_pad = buf.len() != 1 && zero_pad;
197
198 let mut v: Vec<u8>;
200 let bytes: &[u8] = if buf.len() % 2 != 0 {
201 v = Vec::with_capacity(buf.len() + 1);
202 v.push(0);
203 v.extend_from_slice(buf);
204 &v
205 } else {
206 buf
207 };
208
209 let mut timp: usize = bytes.len() / 2;
210 let mut name = String::new();
211 for chunk in bytes.chunks(2) {
212 match chunk {
213 &[pre, suf] => {
214 if name.is_empty() {
215 if zero_pad || pre != 0 {
216 name.push_str(PREFIXES[pre as usize]);
217 }
218 } else {
219 if quad_sep && timp % 4 == 0 {
220 name.push_str("--");
221 } else {
222 name.push_str("-");
223 }
224 name.push_str(PREFIXES[pre as usize]);
225 }
226 name.push_str(SUFFIXES[suf as usize]);
227 }
228 _ => panic!("buf2pat bug!"),
229 }
230 timp = timp - 1;
231 }
232 format!("{}{}", leader, name)
233}
234
235pub fn hex2patq(hex: &str) -> Result<String, Error> {
237 UBig::from_str_radix(hex, 16)
238 .map(|n| big2patq(&n))
239 .map_err(|_| Error::InvalidHex(hex.to_string()))
240}
241
242pub fn hex2patp(hex: &str) -> Result<String, Error> {
244 UBig::from_str_radix(hex, 16)
245 .map(|n| big2patp(&n))
246 .map_err(|_| Error::InvalidHex(hex.to_string()))
247}
248
249pub fn dec2patq(dec: &str) -> Result<String, Error> {
251 UBig::from_str_radix(dec, 10)
252 .map(|n| big2patq(&n))
253 .map_err(|_| Error::InvalidDecimal(dec.to_string()))
254}
255
256pub fn dec2patp(dec: &str) -> Result<String, Error> {
258 UBig::from_str_radix(dec, 10)
259 .map(|n| big2patp(&n))
260 .map_err(|_| Error::InvalidDecimal(dec.to_string()))
261}
262
263pub fn patq2int<T>(name: &str) -> Result<T, Error>
265where
266 T: TryFrom<UBig>,
267{
268 T::try_from(patq2big(name)?).map_err(|_| Error::OutOfBounds)
269}
270
271pub fn patp2int<T>(name: &str) -> Result<T, Error>
273where
274 T: TryFrom<UBig>,
275{
276 T::try_from(patp2big(name)?).map_err(|_| Error::OutOfBounds)
277}
278
279pub fn patq2big(name: &str) -> Result<UBig, Error> {
281 let syls = patq2syls(name)?;
282 let buf = syls2buffer(&syls)?;
283
284 Ok(UBig::from_be_bytes(&buf))
285}
286
287pub fn patp2big(name: &str) -> Result<UBig, Error> {
289 let syls = patp2syls(name)?;
290 let buf = syls2buffer(&syls)?;
291
292 Ok(fynd(&UBig::from_be_bytes(&buf)))
293}
294
295pub fn patp2syls(pat: &str) -> Result<Vec<&str>, Error> {
297 pat2syls(pat, "~", true, true)
298}
299
300pub fn patq2syls(pat: &str) -> Result<Vec<&str>, Error> {
302 pat2syls(pat, ".~", false, false)
303}
304
305pub fn pat2syls(
307 pat: &str,
308 leader: &str,
309 zero_pad: bool,
310 quad_sep: bool,
311) -> Result<Vec<&'static str>, Error> {
312 if let Some(rest) = pat.strip_prefix(leader) {
313 let words: Vec<&str> = rest.split('-').collect();
314 if words.len() == 1 && words[0].len() == 3 {
315 static_suf(words[0]).map(|s| vec![s])
317 } else {
318 let mut empties = 0;
320 for (i, word) in words.iter().rev().enumerate() {
321 if quad_sep && i % 5 == 4 {
322 if !word.is_empty() {
323 return Err(Error::InvalidSeparator);
324 } else {
325 empties += 1;
326 }
327 } else if word.is_empty() {
328 return Err(Error::InvalidSeparator);
329 }
330 }
331
332 let mut syls = Vec::with_capacity((words.len() - empties) * 2);
334 let mut first_word = true;
335 for word in words.iter().filter(|s| !s.is_empty()) {
336 if word.len() == 6 {
337 let (pre, suf) = word.split_at(3);
338 syls.push(static_pre(pre)?);
339 syls.push(static_suf(suf)?);
340 } else if word.len() == 3 && first_word {
341 if !zero_pad {
342 syls.push(static_suf(word)?);
343 } else {
344 return Err(Error::ZeroPadRequired);
345 }
346 } else {
347 return Err(Error::InvalidSection(word.to_string()));
348 }
349 first_word = false;
350 }
351 Ok(syls)
352 }
353 } else {
354 Err(Error::LeaderMissing(leader.to_string()))
355 }
356}
357
358pub fn syls2buffer(syls: &[&str]) -> Result<Vec<u8>, Error> {
360 let mut suffix: bool = syls.len() % 2 == 1;
362 let mut buf = Vec::with_capacity(syls.len());
363 for syl in syls.iter() {
364 if suffix {
365 buf.push(suffix_value(syl)?);
366 } else {
367 buf.push(prefix_value(syl)?);
368 }
369 suffix = !suffix;
370 }
371 Ok(buf)
372}
373
374pub fn patq2hex(name: &str) -> Result<String, Error> {
376 patq2big(name).map(big2hex)
377}
378
379pub fn patp2hex(name: &str) -> Result<String, Error> {
381 patp2big(name).map(big2hex)
382}
383
384fn big2hex(n: UBig) -> String {
386 let hex = n.in_radix(16).to_string();
387 if hex.len() % 2 != 0 {
388 format!("0{hex}")
389 } else {
390 hex
391 }
392}
393
394pub fn patq2dec(name: &str) -> Result<String, Error> {
396 patq2big(name).map(|n| n.in_radix(10).to_string())
397}
398
399pub fn patp2dec(name: &str) -> Result<String, Error> {
401 patp2big(name).map(|n| n.in_radix(10).to_string())
402}
403
404pub fn clan(who: &str) -> Result<&'static str, Error> {
406 let n = patp2big(who)?;
407 let wid = met(3, &n);
408
409 Ok(if wid <= 1 {
410 "galaxy"
411 } else if wid == 2 {
412 "star"
413 } else if wid <= 4 {
414 "planet"
415 } else if wid <= 8 {
416 "moon"
417 } else {
418 "comet"
419 })
420}
421
422pub fn sein(name: &str) -> Result<String, Error> {
424 let who = patp2big(name)?;
425 let mir = clan(name)?;
426
427 let res = match mir {
428 "galaxy" => who,
429 "star" => end(3, &who),
430 "planet" => end(4, &who),
431 "moon" => end(5, &who),
432 _ => UBig::zero(),
433 };
434
435 Ok(big2patp(&res))
436}
437
438pub fn is_valid_pat(name: &str, leader: &str, force_zero_pad: bool, quad_sep: bool) -> bool {
440 pat2syls(name, leader, force_zero_pad, quad_sep).is_ok()
441}
442
443pub fn is_valid_patp(name: &str) -> bool {
445 patp2syls(name).is_ok()
446}
447
448pub fn is_valid_patq(name: &str) -> bool {
450 patq2syls(name).is_ok()
451}
452
453pub fn eq_patq(p: &str, q: &str) -> Result<bool, Error> {
455 let p_val = patp2big(p)?;
456 let q_val = patq2big(q)?;
457 Ok(p_val == q_val)
458}
459
460#[cfg(test)]
461mod tests {
462 #[allow(unused_imports)]
463 use super::*;
464
465 #[test]
466 fn test_patq() {
467 assert_eq!(patq(0_u32), ".~zod");
468 assert_eq!(patq(0xac_u32), ".~ber");
469 assert_eq!(patq(0x23ec_u32), ".~rovfed");
470 assert_eq!(patq(0x94cf670c_u32), ".~mocwel-magwep");
471 assert_eq!(patq(0xe57f1c2d_u32), ".~sarmed-rinbyn");
472 assert_eq!(
473 patq(0xed816cd86003df88_u64),
474 ".~rivdus-timret-ronwes-hocres"
475 );
476 assert_eq!(patq(0xd86003df88_u64), ".~ret-ronwes-hocres");
477 assert_eq!(
478 patq(0x85613e0edad57f5fddc48d3f5808a628_u128),
479 ".~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem"
480 );
481 }
482
483 #[test]
484 fn test_patp() {
485 assert_eq!(patp(0_u32), "~zod");
486 assert_eq!(patp(0xac_u32), "~ber");
487 assert_eq!(patp(0x23ec_u32), "~rovfed");
488 assert_eq!(patp(0x94cf670c_u32), "~lapsen-hapmeb");
489 assert_eq!(patp(0xe57f1c2d_u32), "~hobpur-habnev");
490 assert_eq!(patp(0xed816cd86003df88_u64), "~rivdus-timret-tardet-paslux");
491 assert_eq!(patp(0xd86003df88_u64), "~dozret-tardet-paslux");
492 assert_eq!(
493 patp(0x85613e0edad57f5fddc48d3f5808a628_u128),
494 "~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem"
495 );
496 }
497
498 #[test]
499 fn test_hex2patq() {
500 assert_eq!(hex2patq("0").unwrap(), ".~zod");
501 assert_eq!(hex2patq("ac").unwrap(), ".~ber");
502 assert_eq!(hex2patq("23ec").unwrap(), ".~rovfed");
503 assert_eq!(hex2patq("94cf670c").unwrap(), ".~mocwel-magwep");
504 assert_eq!(hex2patq("e57f1c2d").unwrap(), ".~sarmed-rinbyn");
505 assert_eq!(
506 hex2patq("ed816cd86003df88").unwrap(),
507 ".~rivdus-timret-ronwes-hocres"
508 );
509 assert_eq!(hex2patq("d86003df88").unwrap(), ".~ret-ronwes-hocres");
510 assert_eq!(
511 hex2patq("85613e0edad57f5fddc48d3f5808a628").unwrap(),
512 ".~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem"
513 );
514 }
515
516 #[test]
517 fn test_hex2patp() {
518 assert_eq!(hex2patp("0").unwrap(), "~zod");
519 assert_eq!(hex2patp("ac").unwrap(), "~ber");
520 assert_eq!(hex2patp("23ec").unwrap(), "~rovfed");
521 assert_eq!(hex2patp("94cf670c").unwrap(), "~lapsen-hapmeb");
522 assert_eq!(hex2patp("e57f1c2d").unwrap(), "~hobpur-habnev");
523 assert_eq!(
524 hex2patp("ed816cd86003df88").unwrap(),
525 "~rivdus-timret-tardet-paslux"
526 );
527 assert_eq!(hex2patp("d86003df88").unwrap(), "~dozret-tardet-paslux");
528 assert_eq!(
529 hex2patp("85613e0edad57f5fddc48d3f5808a628").unwrap(),
530 "~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem"
531 );
532 }
533
534 #[test]
535 fn test_dec2patq() {
536 assert_eq!(dec2patq("0").unwrap(), ".~zod");
537 assert_eq!(dec2patq("213").unwrap(), ".~hes");
538 assert_eq!(dec2patq("42345").unwrap(), ".~pindet");
539 assert_eq!(dec2patq("1767345876").unwrap(), ".~davnyx-sopnes");
540 assert_eq!(dec2patq("3825024628").unwrap(), ".~walnel-middut");
541 assert_eq!(
542 dec2patq("946825410821165233").unwrap(),
543 ".~sabsep-ragsud-milnet-rigsud"
544 );
545 assert_eq!(
546 dec2patq("946825410821165").unwrap(),
547 ".~wes-mormep-ponrul-borbyn"
548 );
549 assert_eq!(
550 dec2patq("123944546871737295045108034582151365233").unwrap(),
551 ".~mornep-dinfyr-fognut-folheb-rivrem-wanteg-haprev-binter"
552 );
553 }
554
555 #[test]
556 fn test_dec2patp() {
557 assert_eq!(dec2patp("0").unwrap(), "~zod");
558 assert_eq!(dec2patp("213").unwrap(), "~hes");
559 assert_eq!(dec2patp("42345").unwrap(), "~pindet");
560 assert_eq!(dec2patp("1767345876").unwrap(), "~sabhut-mocsed");
561 assert_eq!(dec2patp("3825024628").unwrap(), "~napdut-matful");
562 assert_eq!(
563 dec2patp("946825410821165233").unwrap(),
564 "~sabsep-ragsud-sicsug-solmud"
565 );
566 assert_eq!(
567 dec2patp("946825410821165").unwrap(),
568 "~dozwes-mormep-simred-novtyd"
569 );
570 assert_eq!(
571 dec2patp("123944546871737295045108034582151365233").unwrap(),
572 "~mornep-dinfyr-fognut-folheb--rivrem-wanteg-haprev-binter"
573 );
574 }
575
576 #[test]
577 fn test_patp2syls() {
578 assert!(matches!(patp2syls("~xxx"), Err(Error::InvalidSuffix(_))));
579 assert!(matches!(
580 patp2syls("~sampel-palxxx"),
581 Err(Error::InvalidSuffix(_))
582 ));
583 assert!(matches!(
584 patp2syls("~sampel-xxxnet"),
585 Err(Error::InvalidPrefix(_))
586 ));
587 assert!(matches!(
588 patp2syls("~dev-sampel-palnet"),
589 Err(Error::ZeroPadRequired)
590 ));
591 assert!(matches!(patp2syls("~dozdev-sampel-palnet"), Ok(_)));
592 assert!(matches!(
593 patp2syls("sampel-palnet"),
594 Err(Error::LeaderMissing(_))
595 ));
596 assert!(matches!(
597 patp2syls(".~sampel-palnet"),
598 Err(Error::LeaderMissing(_))
599 ));
600 assert!(matches!(
601 patp2syls("~sampel-word-palnet"),
602 Err(Error::InvalidSection(_))
603 ));
604 assert!(matches!(
605 patp2syls("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem"),
606 Ok(_)
607 ));
608 assert!(matches!(
609 patp2syls("~palsym--fotnul-pagpur-nopful-lomtem"),
610 Ok(_)
611 ));
612 assert!(matches!(
613 patp2syls("~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem"),
614 Err(Error::InvalidSeparator)
615 ));
616 assert!(matches!(
617 patp2syls("~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful--lomtem"),
618 Err(Error::InvalidSeparator)
619 ));
620 }
621
622 #[test]
623 fn test_patq2syls() {
624 assert!(matches!(patq2syls(".~xxx"), Err(Error::InvalidSuffix(_))));
625 assert!(matches!(
626 patq2syls(".~sampel-palxxx"),
627 Err(Error::InvalidSuffix(_))
628 ));
629 assert!(matches!(
630 patq2syls(".~sampel-xxxnet"),
631 Err(Error::InvalidPrefix(_))
632 ));
633 assert!(matches!(patq2syls(".~dev-sampel-palnet"), Ok(_)));
634 assert!(matches!(patq2syls(".~dozdev-sampel-palnet"), Ok(_)));
635 assert!(matches!(
636 patq2syls("sampel-palnet"),
637 Err(Error::LeaderMissing(_))
638 ));
639 assert!(matches!(
640 patq2syls("~sampel-palnet"),
641 Err(Error::LeaderMissing(_))
642 ));
643 assert!(matches!(
644 patq2syls(".~sampel-word-palnet"),
645 Err(Error::InvalidSection(_))
646 ));
647 assert!(matches!(
648 patq2syls(".~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem"),
649 Err(Error::InvalidSeparator)
650 ));
651 assert!(matches!(
652 patq2syls(".~rolruc--midwyl-hathes--palsym-fotnul--pagpur-nopful--lomtem"),
653 Err(Error::InvalidSeparator)
654 ));
655 }
656
657 #[test]
658 fn test_patp2int() {
659 assert_eq!(patp2int::<u16>("~binzod").unwrap(), 512);
660 assert_eq!(patp2int::<u32>("~sampel-palnet").unwrap(), 1624961343);
661 assert_eq!(
662 patp2int::<u64>("~mastyr-midwyt-sampel-palnet").unwrap(),
663 14598768375314968895
664 );
665 assert!(matches!(
666 patp2int::<u32>("~mastyr-midwyt-sampel-palnet"),
667 Err(Error::OutOfBounds)
668 ));
669 assert_eq!(
670 patp2int::<u128>("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem").unwrap(),
671 177292234920987225829036013324996224552
672 );
673 assert!(matches!(
674 patp2int::<u128>("~mastyr--rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem"),
675 Err(Error::OutOfBounds)
676 ));
677 }
678
679 #[test]
680 fn test_patq2int() {
681 assert_eq!(patq2int::<u16>(".~binzod").unwrap(), 512);
682 assert_eq!(patq2int::<u32>(".~sampel-palnet").unwrap(), 74415951);
683 assert_eq!(
684 patq2int::<u64>(".~mastyr-midwyt-sampel-palnet").unwrap(),
685 14598768373764423503
686 );
687 assert!(matches!(
688 patq2int::<u32>(".~mastyr-midwyt-sampel-palnet"),
689 Err(Error::OutOfBounds)
690 ));
691 assert_eq!(
692 patq2int::<u128>(".~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem").unwrap(),
693 177292234920987225829036013324996224552
694 );
695 assert!(matches!(
696 patq2int::<u128>(".~mastyr-rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem"),
697 Err(Error::OutOfBounds)
698 ));
699 }
700
701 #[test]
702 fn test_patp2dec() {
703 assert_eq!(patp2dec("~binzod").unwrap(), "512");
704 assert_eq!(patp2dec("~sampel-palnet").unwrap(), "1624961343");
705 assert_eq!(
706 patp2dec("~mastyr-midwyt-sampel-palnet").unwrap(),
707 "14598768375314968895"
708 );
709 assert_eq!(
710 patp2dec("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem").unwrap(),
711 "177292234920987225829036013324996224552"
712 );
713 }
714
715 #[test]
716 fn test_patq2dec() {
717 assert_eq!(patq2dec(".~binzod").unwrap(), "512");
718 assert_eq!(patq2dec(".~sampel-palnet").unwrap(), "74415951");
719 assert_eq!(
720 patq2dec(".~mastyr-midwyt-sampel-palnet").unwrap(),
721 "14598768373764423503"
722 );
723 assert_eq!(
724 patq2dec(".~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem").unwrap(),
725 "177292234920987225829036013324996224552"
726 );
727 }
728
729 #[test]
730 fn test_patp2hex() {
731 assert_eq!(patp2hex("~binzod").unwrap(), "0200");
732 assert_eq!(patp2hex("~sampel-palnet").unwrap(), "60daf13f");
733 assert_eq!(
734 patp2hex("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem").unwrap(),
735 "85613e0edad57f5fddc48d3f5808a628"
736 );
737 }
738
739 #[test]
740 fn test_patq2hex() {
741 assert_eq!(patq2hex(".~binzod").unwrap(), "0200");
742 assert_eq!(patq2hex(".~sampel-palnet").unwrap(), "046f7f4f");
743 assert_eq!(
744 patq2hex(".~rolruc-midwyl-hathes-palsym-fotnul-pagpur-nopful-lomtem").unwrap(),
745 "85613e0edad57f5fddc48d3f5808a628"
746 );
747 }
748
749 #[test]
750 fn test_clan() {
751 assert_eq!(clan("~zod").unwrap(), "galaxy");
752 assert_eq!(clan("~binzod").unwrap(), "star");
753 assert_eq!(clan("~sampel-palnet").unwrap(), "planet");
754 assert_eq!(clan("~rolruc-midwyl-hathes-palsym").unwrap(), "moon");
755 assert_eq!(
756 clan("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem").unwrap(),
757 "comet"
758 );
759 }
760
761 #[test]
762 fn test_sein() {
763 assert_eq!(sein("~dev").unwrap(), "~dev");
764 assert_eq!(sein("~binhut").unwrap(), "~hut");
765 assert_eq!(sein("~sampel-palnet").unwrap(), "~talpur");
766 assert_eq!(
767 sein("~rolruc-midwyl-hathes-palsym").unwrap(),
768 "~hathes-palsym"
769 );
770 assert_eq!(
771 sein("~rolruc-midwyl-hathes-palsym--fotnul-pagpur-nopful-lomtem").unwrap(),
772 "~zod"
773 );
774 }
775}