Skip to main content

ord/
representation.rs

1use {super::*, regex::RegexSet};
2
3#[derive(Debug, Copy, Clone)]
4pub(crate) enum Representation {
5  Address,
6  Decimal,
7  Degree,
8  Hash,
9  InscriptionId,
10  Integer,
11  Name,
12  OutPoint,
13  Percentile,
14  Rune,
15  SatPoint,
16}
17
18impl Representation {
19  const fn pattern(self) -> (Self, &'static str) {
20    (
21      self,
22      match self {
23        Self::Address => r"^(bc|BC|tb|TB|bcrt|BCRT)1.*$",
24        Self::Decimal => r"^.*\..*$",
25        Self::Degree => r"^.*°.*′.*″(.*‴)?$",
26        Self::Hash => r"^[[:xdigit:]]{64}$",
27        Self::InscriptionId => r"^[[:xdigit:]]{64}i\d+$",
28        Self::Integer => r"^[0-9]*$",
29        Self::Name => r"^[a-z]{1,11}$",
30        Self::OutPoint => r"^[[:xdigit:]]{64}:\d+$",
31        Self::Percentile => r"^.*%$",
32        Self::Rune => r"^[A-Z•.]+$",
33        Self::SatPoint => r"^[[:xdigit:]]{64}:\d+:\d+$",
34      },
35    )
36  }
37}
38
39impl FromStr for Representation {
40  type Err = SnafuError;
41
42  fn from_str(input: &str) -> Result<Self, Self::Err> {
43    if let Some(i) = REGEX_SET.matches(input).into_iter().next() {
44      Ok(PATTERNS[i].0)
45    } else {
46      Err(error::UnrecognizedRepresentation { input }.build())
47    }
48  }
49}
50
51const PATTERNS: &[(Representation, &str)] = &[
52  Representation::Address.pattern(),
53  Representation::Decimal.pattern(),
54  Representation::Degree.pattern(),
55  Representation::Hash.pattern(),
56  Representation::InscriptionId.pattern(),
57  Representation::Integer.pattern(),
58  Representation::Name.pattern(),
59  Representation::OutPoint.pattern(),
60  Representation::Percentile.pattern(),
61  Representation::Rune.pattern(),
62  Representation::SatPoint.pattern(),
63];
64
65static REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {
66  RegexSet::new(PATTERNS.iter().map(|(_representation, pattern)| pattern)).unwrap()
67});
68
69#[cfg(test)]
70mod tests {
71  use super::*;
72
73  #[test]
74  fn all_patterns_are_anchored() {
75    assert!(
76      PATTERNS
77        .iter()
78        .all(|(_representation, pattern)| pattern.starts_with('^') && pattern.ends_with('$'))
79    );
80  }
81}