hopper_core/abi/
field_ref.rs1use hopper_runtime::error::ProgramError;
8
9#[derive(Clone, Copy)]
11pub struct FieldRef<'a> {
12 data: &'a [u8],
13}
14
15impl<'a> FieldRef<'a> {
16 #[inline(always)]
18 pub const fn new(data: &'a [u8]) -> Self {
19 Self { data }
20 }
21
22 #[inline(always)]
24 pub const fn as_bytes(&self) -> &[u8] {
25 self.data
26 }
27
28 #[inline(always)]
30 pub fn read_u8(&self) -> Result<u8, ProgramError> {
31 self.data
32 .first()
33 .copied()
34 .ok_or(ProgramError::InvalidAccountData)
35 }
36
37 #[inline(always)]
39 pub fn read_u16(&self) -> Result<u16, ProgramError> {
40 if self.data.len() < 2 {
41 return Err(ProgramError::InvalidAccountData);
42 }
43 Ok(u16::from_le_bytes([self.data[0], self.data[1]]))
44 }
45
46 #[inline(always)]
48 pub fn read_u32(&self) -> Result<u32, ProgramError> {
49 if self.data.len() < 4 {
50 return Err(ProgramError::InvalidAccountData);
51 }
52 Ok(u32::from_le_bytes([
53 self.data[0],
54 self.data[1],
55 self.data[2],
56 self.data[3],
57 ]))
58 }
59
60 #[inline(always)]
62 pub fn read_u64(&self) -> Result<u64, ProgramError> {
63 if self.data.len() < 8 {
64 return Err(ProgramError::InvalidAccountData);
65 }
66 Ok(u64::from_le_bytes([
67 self.data[0],
68 self.data[1],
69 self.data[2],
70 self.data[3],
71 self.data[4],
72 self.data[5],
73 self.data[6],
74 self.data[7],
75 ]))
76 }
77
78 #[inline(always)]
80 pub fn read_bool(&self) -> Result<bool, ProgramError> {
81 self.read_u8().map(|v| v != 0)
82 }
83
84 #[inline(always)]
86 pub fn as_address(&self) -> Result<&[u8; 32], ProgramError> {
87 if self.data.len() < 32 {
88 return Err(ProgramError::InvalidAccountData);
89 }
90 Ok(unsafe { &*(self.data.as_ptr() as *const [u8; 32]) })
92 }
93}
94
95pub struct FieldMut<'a> {
97 data: &'a mut [u8],
98}
99
100impl<'a> FieldMut<'a> {
101 #[inline(always)]
103 pub fn new(data: &'a mut [u8]) -> Self {
104 Self { data }
105 }
106
107 #[inline(always)]
109 pub fn read_u8(&self) -> Result<u8, ProgramError> {
110 self.data
111 .first()
112 .copied()
113 .ok_or(ProgramError::InvalidAccountData)
114 }
115
116 #[inline(always)]
118 pub fn read_u64(&self) -> Result<u64, ProgramError> {
119 if self.data.len() < 8 {
120 return Err(ProgramError::InvalidAccountData);
121 }
122 Ok(u64::from_le_bytes([
123 self.data[0],
124 self.data[1],
125 self.data[2],
126 self.data[3],
127 self.data[4],
128 self.data[5],
129 self.data[6],
130 self.data[7],
131 ]))
132 }
133
134 #[inline(always)]
136 pub fn write_u8(&mut self, v: u8) -> Result<(), ProgramError> {
137 if self.data.is_empty() {
138 return Err(ProgramError::InvalidAccountData);
139 }
140 self.data[0] = v;
141 Ok(())
142 }
143
144 #[inline(always)]
146 pub fn write_u16(&mut self, v: u16) -> Result<(), ProgramError> {
147 if self.data.len() < 2 {
148 return Err(ProgramError::InvalidAccountData);
149 }
150 let bytes = v.to_le_bytes();
151 self.data[0] = bytes[0];
152 self.data[1] = bytes[1];
153 Ok(())
154 }
155
156 #[inline(always)]
158 pub fn write_u32(&mut self, v: u32) -> Result<(), ProgramError> {
159 if self.data.len() < 4 {
160 return Err(ProgramError::InvalidAccountData);
161 }
162 let bytes = v.to_le_bytes();
163 self.data[..4].copy_from_slice(&bytes);
164 Ok(())
165 }
166
167 #[inline(always)]
169 pub fn write_u64(&mut self, v: u64) -> Result<(), ProgramError> {
170 if self.data.len() < 8 {
171 return Err(ProgramError::InvalidAccountData);
172 }
173 let bytes = v.to_le_bytes();
174 self.data[..8].copy_from_slice(&bytes);
175 Ok(())
176 }
177
178 #[inline(always)]
180 pub fn write_bool(&mut self, v: bool) -> Result<(), ProgramError> {
181 self.write_u8(v as u8)
182 }
183
184 #[inline(always)]
186 pub fn write_address(&mut self, addr: &[u8; 32]) -> Result<(), ProgramError> {
187 if self.data.len() < 32 {
188 return Err(ProgramError::InvalidAccountData);
189 }
190 self.data[..32].copy_from_slice(addr);
191 Ok(())
192 }
193
194 #[inline(always)]
196 pub fn copy_from(&mut self, src: &[u8]) -> Result<(), ProgramError> {
197 if self.data.len() < src.len() {
198 return Err(ProgramError::InvalidAccountData);
199 }
200 self.data[..src.len()].copy_from_slice(src);
201 Ok(())
202 }
203
204 #[inline(always)]
206 pub fn as_bytes(&self) -> &[u8] {
207 self.data
208 }
209
210 #[inline(always)]
212 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
213 self.data
214 }
215}