alloy_primitives/bits/
function.rs1use crate::{Address, FixedBytes, Selector};
2use core::borrow::Borrow;
3
4wrap_fixed_bytes! {
5 pub struct Function<24>;
10}
11
12impl<A, S> From<(A, S)> for Function
13where
14 A: Borrow<[u8; 20]>,
15 S: Borrow<[u8; 4]>,
16{
17 #[inline]
18 fn from((address, selector): (A, S)) -> Self {
19 Self::from_address_and_selector(address, selector)
20 }
21}
22
23impl Function {
24 #[inline]
30 #[must_use]
31 pub fn from_word(word: FixedBytes<32>) -> Self {
32 Self(FixedBytes(word[..24].try_into().unwrap()))
33 }
34
35 #[inline]
40 #[must_use]
41 pub fn into_word(&self) -> FixedBytes<32> {
42 let mut word = [0; 32];
43 word[..24].copy_from_slice(self.as_slice());
44 FixedBytes(word)
45 }
46
47 #[inline]
49 pub fn from_address_and_selector<A, S>(address: A, selector: S) -> Self
50 where
51 A: Borrow<[u8; 20]>,
52 S: Borrow<[u8; 4]>,
53 {
54 let mut bytes = [0; 24];
55 bytes[..20].copy_from_slice(address.borrow());
56 bytes[20..].copy_from_slice(selector.borrow());
57 Self(FixedBytes(bytes))
58 }
59
60 #[inline]
62 pub fn as_address_and_selector(&self) -> (&Address, &Selector) {
63 unsafe { (&*self.as_ptr().cast(), &*self.as_ptr().add(20).cast()) }
65 }
66
67 #[inline]
69 pub fn to_address_and_selector(&self) -> (Address, Selector) {
70 let (a, s) = self.as_address_and_selector();
71 (*a, *s)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::hex;
79
80 #[test]
81 fn function_parts() {
82 let f = Function::new(hex!(
83 "
84 ffffffffffffffffffffffffffffffffffffffff
85 12345678
86 "
87 ));
88
89 let (a1, s1) = f.as_address_and_selector();
90 assert_eq!(a1, hex!("ffffffffffffffffffffffffffffffffffffffff"));
91 assert_eq!(s1, &hex!("12345678"));
92
93 let (a2, s2) = f.to_address_and_selector();
94 assert_eq!(a2, *a1);
95 assert_eq!(s2, *s1);
96 }
97}