hopper_native/
capability.rs1use crate::account_view::AccountView;
32use crate::address::Address;
33use crate::error::ProgramError;
34
35#[repr(transparent)]
43#[derive(Clone, PartialEq, Eq)]
44pub struct SignerView<'info> {
45 inner: AccountView<'info>,
46}
47
48impl<'info> SignerView<'info> {
49 #[inline(always)]
51 pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
52 if view.is_signer() {
53 Ok(Self { inner: view })
54 } else {
55 Err(ProgramError::MissingRequiredSignature)
56 }
57 }
58
59 #[inline(always)]
61 pub fn as_view(&self) -> &AccountView<'info> {
62 &self.inner
63 }
64
65 #[inline(always)]
67 pub fn into_view(self) -> AccountView<'info> {
68 self.inner
69 }
70}
71
72impl<'info> core::ops::Deref for SignerView<'info> {
73 type Target = AccountView<'info>;
74
75 #[inline(always)]
76 fn deref(&self) -> &AccountView<'info> {
77 &self.inner
78 }
79}
80
81#[repr(transparent)]
87#[derive(Clone, PartialEq, Eq)]
88pub struct WritableView<'info> {
89 inner: AccountView<'info>,
90}
91
92impl<'info> WritableView<'info> {
93 #[inline(always)]
95 pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
96 if view.is_writable() {
97 Ok(Self { inner: view })
98 } else {
99 Err(ProgramError::Immutable)
100 }
101 }
102
103 #[inline(always)]
105 pub fn as_view(&self) -> &AccountView<'info> {
106 &self.inner
107 }
108
109 #[inline(always)]
111 pub fn into_view(self) -> AccountView<'info> {
112 self.inner
113 }
114}
115
116impl<'info> core::ops::Deref for WritableView<'info> {
117 type Target = AccountView<'info>;
118
119 #[inline(always)]
120 fn deref(&self) -> &AccountView<'info> {
121 &self.inner
122 }
123}
124
125#[repr(transparent)]
133#[derive(Clone, PartialEq, Eq)]
134pub struct MutableView<'info> {
135 inner: AccountView<'info>,
136}
137
138impl<'info> MutableView<'info> {
139 #[inline(always)]
141 pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
142 if !view.is_signer() {
143 return Err(ProgramError::MissingRequiredSignature);
144 }
145 if !view.is_writable() {
146 return Err(ProgramError::Immutable);
147 }
148 Ok(Self { inner: view })
149 }
150
151 #[inline(always)]
153 pub fn as_view(&self) -> &AccountView<'info> {
154 &self.inner
155 }
156
157 #[inline(always)]
159 pub fn into_view(self) -> AccountView<'info> {
160 self.inner
161 }
162
163 #[inline(always)]
165 pub fn as_signer(&self) -> SignerView<'info> {
166 SignerView {
168 inner: self.inner.clone(),
169 }
170 }
171
172 #[inline(always)]
174 pub fn as_writable(&self) -> WritableView<'info> {
175 WritableView {
177 inner: self.inner.clone(),
178 }
179 }
180}
181
182impl<'info> core::ops::Deref for MutableView<'info> {
183 type Target = AccountView<'info>;
184
185 #[inline(always)]
186 fn deref(&self) -> &AccountView<'info> {
187 &self.inner
188 }
189}
190
191#[repr(transparent)]
198#[derive(Clone, PartialEq, Eq)]
199pub struct OwnedView<'info> {
200 inner: AccountView<'info>,
201}
202
203impl<'info> OwnedView<'info> {
204 #[inline(always)]
206 pub fn validate(
207 view: AccountView<'info>,
208 expected_owner: &Address,
209 ) -> Result<Self, ProgramError> {
210 if view.owned_by(expected_owner) {
211 Ok(Self { inner: view })
212 } else {
213 Err(ProgramError::IncorrectProgramId)
214 }
215 }
216
217 #[inline(always)]
219 pub fn as_view(&self) -> &AccountView<'info> {
220 &self.inner
221 }
222
223 #[inline(always)]
225 pub fn into_view(self) -> AccountView<'info> {
226 self.inner
227 }
228}
229
230impl<'info> core::ops::Deref for OwnedView<'info> {
231 type Target = AccountView<'info>;
232
233 #[inline(always)]
234 fn deref(&self) -> &AccountView<'info> {
235 &self.inner
236 }
237}
238
239#[repr(transparent)]
245#[derive(Clone, PartialEq, Eq)]
246pub struct ReadonlyView<'info> {
247 inner: AccountView<'info>,
248}
249
250impl<'info> ReadonlyView<'info> {
251 #[inline(always)]
253 pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
254 if view.is_writable() {
259 return Err(ProgramError::InvalidArgument);
261 }
262 Ok(Self { inner: view })
263 }
264
265 #[inline(always)]
267 pub fn as_view(&self) -> &AccountView<'info> {
268 &self.inner
269 }
270
271 #[inline(always)]
273 pub fn into_view(self) -> AccountView<'info> {
274 self.inner
275 }
276}
277
278impl<'info> core::ops::Deref for ReadonlyView<'info> {
279 type Target = AccountView<'info>;
280
281 #[inline(always)]
282 fn deref(&self) -> &AccountView<'info> {
283 &self.inner
284 }
285}
286
287#[repr(transparent)]
294#[derive(Clone, PartialEq, Eq)]
295pub struct ExecutableView<'info> {
296 inner: AccountView<'info>,
297}
298
299impl<'info> ExecutableView<'info> {
300 #[inline(always)]
302 pub fn validate(view: AccountView<'info>) -> Result<Self, ProgramError> {
303 if view.executable() {
304 Ok(Self { inner: view })
305 } else {
306 Err(ProgramError::InvalidArgument)
307 }
308 }
309
310 #[inline(always)]
312 pub fn as_view(&self) -> &AccountView<'info> {
313 &self.inner
314 }
315
316 #[inline(always)]
318 pub fn into_view(self) -> AccountView<'info> {
319 self.inner
320 }
321}
322
323impl<'info> core::ops::Deref for ExecutableView<'info> {
324 type Target = AccountView<'info>;
325
326 #[inline(always)]
327 fn deref(&self) -> &AccountView<'info> {
328 &self.inner
329 }
330}
331
332impl<'info> crate::lazy::LazyContext<'info> {
335 #[inline]
337 pub fn next_validated_signer(&mut self) -> Result<SignerView<'info>, ProgramError> {
338 let acct = self.next_account()?;
339 SignerView::validate(acct)
340 }
341
342 #[inline]
344 pub fn next_validated_writable(&mut self) -> Result<WritableView<'info>, ProgramError> {
345 let acct = self.next_account()?;
346 WritableView::validate(acct)
347 }
348
349 #[inline]
351 pub fn next_validated_mutable(&mut self) -> Result<MutableView<'info>, ProgramError> {
352 let acct = self.next_account()?;
353 MutableView::validate(acct)
354 }
355
356 #[inline]
358 pub fn next_validated_owned(
359 &mut self,
360 owner: &Address,
361 ) -> Result<OwnedView<'info>, ProgramError> {
362 let acct = self.next_account()?;
363 OwnedView::validate(acct, owner)
364 }
365
366 #[inline]
368 pub fn next_validated_executable(&mut self) -> Result<ExecutableView<'info>, ProgramError> {
369 let acct = self.next_account()?;
370 ExecutableView::validate(acct)
371 }
372}