phink_lib/contract/selectors/
selector.rs

1use anyhow::bail;
2use std::{
3    fmt::{
4        Display,
5        Formatter,
6    },
7    str::FromStr,
8};
9
10#[derive(PartialEq, Clone, Debug, Copy)]
11pub struct Selector(pub [u8; 4]);
12
13impl Display for Selector {
14    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15        f.write_str(&hex::encode(self.0))
16    }
17}
18
19impl FromStr for Selector {
20    type Err = anyhow::Error;
21    /// Decode a hexadecimal string selector into a byte
22    /// array of length 4. Returns `None` if the decoding or conversion
23    /// fails.
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        let trimmed = hex::decode(s.trim_start_matches("0x"))?;
26        if trimmed.len() != 4 {
27            bail!("Decoded hex does not match the expected length of 4");
28        }
29        match Selector::try_from(trimmed.to_vec()) {
30            Ok(sel) => Ok(sel),
31            Err(e) => bail!(format!("Couldn't parse the selector {s} because {e}").to_string()),
32        }
33    }
34}
35
36impl AsMut<[u8]> for Selector {
37    fn as_mut(&mut self) -> &mut [u8] {
38        &mut self.0
39    }
40}
41
42impl AsRef<[u8]> for Selector {
43    fn as_ref(&self) -> &[u8] {
44        &self.0
45    }
46}
47
48impl From<[u8; 4]> for Selector {
49    fn from(value: [u8; 4]) -> Self {
50        Self(value)
51    }
52}
53
54impl From<Selector> for Vec<u8> {
55    fn from(selector: Selector) -> Self {
56        selector.0.to_vec()
57    }
58}
59
60impl TryFrom<&str> for Selector {
61    type Error = anyhow::Error;
62
63    fn try_from(value: &str) -> Result<Self, Self::Error> {
64        let value = value.trim_start_matches("0x"); // Remove "0x" if present
65        let bytes = hex::decode(value)?;
66        Selector::try_from(bytes.as_slice())
67    }
68}
69
70impl TryFrom<&[u8]> for Selector {
71    type Error = anyhow::Error;
72
73    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
74        if value.len() != 4 {
75            return Err(anyhow::anyhow!("Invalid lenght for selector"));
76        }
77        let mut array = [0u8; 4];
78        array.copy_from_slice(value);
79        Ok(Selector(array))
80    }
81}
82
83impl TryFrom<Vec<u8>> for Selector {
84    type Error = anyhow::Error;
85
86    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
87        value.as_slice().try_into()
88    }
89}