phink_lib/contract/selectors/
selector.rs1use 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 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"); 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}