slen/
lib.rs

1extern crate array_init;
2extern crate substring;
3
4pub mod splat1;
5pub use splat1::S1Loadout;
6
7pub mod splat2;
8pub use splat2::S2Loadout;
9
10/// A Splatoon-series loadout.
11///
12/// Loadouts can be parsed using their [`std::str::FromStr`] implementation,
13/// with a prefix of `sx:` (where `x` is the series entry) to signal what kind
14/// of loadout to parse.
15#[derive(Debug, PartialEq, Eq)]
16pub enum Loadout {
17    Splat1(S1Loadout),
18    Splat2(S2Loadout),
19}
20
21impl std::str::FromStr for Loadout {
22    type Err = ParseFailure;
23
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        if let Some((prefix, code)) = s.split_once(':') {
26            match prefix {
27                "s1" => Ok(Self::Splat1(code.parse()?)),
28                "s2" => Ok(Self::Splat2(code.parse()?)),
29                _ => Err(ParseFailure::Prefix),
30            }
31        } else {
32            Err(ParseFailure::Value)
33        }
34    }
35}
36
37impl std::fmt::Display for Loadout {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        match self {
40            Loadout::Splat1(s) => write!(f, "s1:{}", s),
41            Loadout::Splat2(s) => write!(f, "s2:{}", s),
42        }
43    }
44}
45
46#[derive(Debug)]
47pub enum ParseFailure {
48    Length,
49    Value,
50    Prefix,
51}
52
53fn hexstr_to_bin(s: &str) -> Option<String> {
54    let mut ret = String::new();
55    for c in s.chars() {
56        if let Some(c) = hexchar_to_bin(&c) {
57            ret.push_str(c);
58        } else {
59            return None;
60        }
61    }
62    Some(ret)
63}
64
65#[inline]
66fn hexchar_to_bin(c: &char) -> Option<&str> {
67    Some(match c {
68        '0' => "0000",
69        '1' => "0001",
70        '2' => "0010",
71        '3' => "0011",
72        '4' => "0100",
73        '5' => "0101",
74        '6' => "0110",
75        '7' => "0111",
76        '8' => "1000",
77        '9' => "1001",
78        'a' => "1010",
79        'b' => "1011",
80        'c' => "1100",
81        'd' => "1101",
82        'e' => "1110",
83        'f' => "1111",
84        'A' => "1010",
85        'B' => "1011",
86        'C' => "1100",
87        'D' => "1101",
88        'E' => "1110",
89        _ => return None,
90    })
91}