hayabusa_context/
lib.rs

1// Copyright (c) 2025, Arcane Labs <dev@arcane.fi>
2// SPDX-License-Identifier: Apache-2.0
3
4#![no_std]
5
6use hayabusa_errors::{ErrorCode, Result};
7use hayabusa_utility::fail_with_ctx;
8use pinocchio::account_info::AccountInfo;
9
10pub trait FromAccountInfos<'a>
11where
12    Self: Sized,
13{
14    fn try_from_account_infos(account_infos: &mut AccountIter<'a>) -> Result<Self>;
15}
16
17/// ## Context
18///
19/// A context consists of a set of typed/named accounts `T`
20/// with constraints applied and a remaining accounts iterator.
21pub struct Ctx<'a, T>
22where
23    T: FromAccountInfos<'a>,
24{
25    pub accounts: T,
26    pub remaining_accounts: AccountIter<'a>,
27}
28
29impl<'a, T> Ctx<'a, T>
30where
31    T: FromAccountInfos<'a>,
32{
33    #[inline(always)]
34    pub fn construct(account_infos: &'a [AccountInfo]) -> Result<Self> {
35        let mut iter = AccountIter::new(account_infos);
36
37        let accounts = T::try_from_account_infos(&mut iter)?;
38
39        Ok(Ctx {
40            accounts,
41            remaining_accounts: iter,
42        })
43    }
44}
45
46impl<'a, T> core::ops::Deref for Ctx<'a, T>
47where
48    T: FromAccountInfos<'a>,
49{
50    type Target = T;
51
52    #[inline(always)]
53    fn deref(&self) -> &Self::Target {
54        &self.accounts
55    }
56}
57
58#[derive(Clone)]
59pub struct AccountIter<'a> {
60    slice: &'a [AccountInfo],
61    index: usize,
62}
63
64impl<'a> AccountIter<'a> {
65    #[inline(always)]
66    pub fn new(slice: &'a [AccountInfo]) -> Self {
67        Self { slice, index: 0 }
68    }
69
70    #[allow(clippy::should_implement_trait)]
71    #[inline(always)]
72    pub fn next(&mut self) -> Result<&'a AccountInfo> {
73        if self.index >= self.slice.len() {
74            fail_with_ctx!(
75                "HAYABUSA_ACCOUNT_ITER_NEXT_NOT_PRESENT",
76                ErrorCode::InvalidAccount,
77            );
78        }
79
80        let account_info = &self.slice[self.index];
81        self.index += 1;
82
83        Ok(account_info)
84    }
85}