titan_types/
query.rs

1use {
2    crate::{rune_id::RuneId, spaced_rune::SpacedRune},
3    bitcoin::BlockHash,
4    std::{
5        fmt::{self, Display},
6        str::FromStr,
7    },
8};
9
10#[derive(Debug, thiserror::Error)]
11pub enum BlockParseError {
12    #[error("invalid block height")]
13    InvalidHeight,
14    #[error("invalid block hash")]
15    InvalidHash,
16}
17
18#[derive(Debug)]
19pub enum Block {
20    Height(u64),
21    Hash(BlockHash),
22}
23
24impl FromStr for Block {
25    type Err = BlockParseError;
26
27    fn from_str(s: &str) -> Result<Self, Self::Err> {
28        Ok(if s.len() == 64 {
29            Self::Hash(s.parse().map_err(|_| BlockParseError::InvalidHash)?)
30        } else {
31            Self::Height(s.parse().map_err(|_| BlockParseError::InvalidHeight)?)
32        })
33    }
34}
35
36impl Display for Block {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        match self {
39            Block::Height(height) => write!(f, "{}", height),
40            Block::Hash(hash) => write!(f, "{}", hash),
41        }
42    }
43}
44
45impl Into<String> for Block {
46    fn into(self) -> String {
47        match self {
48            Self::Height(height) => height.to_string(),
49            Self::Hash(hash) => hash.to_string(),
50        }
51    }
52}
53
54#[derive(Debug, thiserror::Error)]
55pub enum RuneParseError {
56    #[error("invalid rune id")]
57    InvalidId,
58    #[error("invalid spaced rune")]
59    InvalidSpacedRune,
60}
61
62#[derive(Debug)]
63pub enum Rune {
64    Spaced(SpacedRune),
65    Id(RuneId),
66}
67
68impl FromStr for Rune {
69    type Err = RuneParseError;
70
71    fn from_str(s: &str) -> Result<Self, Self::Err> {
72        if s.contains(':') {
73            Ok(Self::Id(s.parse().map_err(|_| RuneParseError::InvalidId)?))
74        } else {
75            Ok(Self::Spaced(
76                s.parse().map_err(|_| RuneParseError::InvalidSpacedRune)?,
77            ))
78        }
79    }
80}
81
82impl Display for Rune {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        match self {
85            Self::Spaced(rune) => write!(f, "{}", rune),
86            Self::Id(id) => write!(f, "{}", id),
87        }
88    }
89}
90
91impl Into<String> for Rune {
92    fn into(self) -> String {
93        match self {
94            Self::Spaced(rune) => rune.to_string(),
95            Self::Id(id) => id.to_string(),
96        }
97    }
98}