etk_cli/
parse.rs

1//! Utilities for parsing strings.
2
3use hex::FromHex;
4
5use std::fmt;
6use std::str::FromStr;
7
8/// Wrapper around `T` that uses hexadecimal for `Display` and `FromStr`.
9#[derive(Debug)]
10pub struct Hex<T>(pub T);
11
12/// Errors that can occur while parsing hexadecimal.
13#[derive(Debug)]
14pub enum FromHexError<E> {
15    /// The required `0x` prefix was not found.
16    Prefix,
17
18    /// Parsing the hexadecimal string failed.
19    Hex(E),
20}
21
22impl<E> std::error::Error for FromHexError<E>
23where
24    E: 'static + std::error::Error,
25{
26    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
27        match self {
28            FromHexError::Prefix => None,
29            FromHexError::Hex(ref e) => Some(e),
30        }
31    }
32}
33
34impl<E> fmt::Display for FromHexError<E>
35where
36    E: fmt::Display,
37{
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        match self {
40            FromHexError::Prefix => write!(f, "missing 0x prefix"),
41            FromHexError::Hex(e) => write!(f, "{}", e),
42        }
43    }
44}
45
46impl<T> FromStr for Hex<T>
47where
48    T: FromHex,
49{
50    type Err = FromHexError<<T as FromHex>::Error>;
51
52    fn from_str(txt: &str) -> Result<Self, Self::Err> {
53        let rest = txt.strip_prefix("0x").ok_or(FromHexError::Prefix)?;
54        let item = T::from_hex(rest).map_err(FromHexError::Hex)?;
55        Ok(Self(item))
56    }
57}