hayabusa_instruction_dispatch_macro/
lib.rs

1// Copyright (c) 2025, Arcane Labs <dev@arcane.fi>
2// SPDX-License-Identifier: Apache-2.0
3
4#![no_std]
5
6#[allow(clippy::crate_in_macro_def)]
7#[macro_export]
8macro_rules! dispatch {
9    (
10        $program_id:expr,
11        $ix_data:expr,
12        $accounts:expr,
13        $(
14            $IxTy:ty => $handler:ident ( $($field:ident),* $(,)? )
15        ),+ $(,)?
16    ) => {{
17        if unlikely($program_id != &crate::ID) {
18            fail_with_ctx!(
19                "HAYABUSA_DISPATCH_INCORRECT_PROGRAM_ID",
20                ProgramError::IncorrectProgramId,
21                $program_id,
22            );
23        }
24
25        const DISC_LEN: usize = 8;
26
27        if unlikely($ix_data.len() < DISC_LEN) {
28            fail_with_ctx!(
29                "HAYABUSA_DISPATCH_IX_DATA_LEN",
30                ProgramError::InvalidInstructionData,
31                $ix_data,
32            );
33        }
34
35        let (disc, rest) = $ix_data.split_at(DISC_LEN);
36
37        $(
38            if disc == <$IxTy>::DISCRIMINATOR {
39                let ix = bytemuck::try_from_bytes::<$IxTy>(rest)
40                    .map_err(|_| {
41                        ProgramError::InvalidInstructionData
42                    })?;
43
44                let ctx = Ctx::construct($accounts)?;
45                return $handler(ctx, $(ix.$field),*)
46                    .map_err(Into::into);
47            }
48        )+
49
50        fail_with_ctx!(
51            "HAYABUSA_DISPATCH_UNKNOWN_IX",
52            ErrorCode::UnknownInstruction,
53            disc,
54        );
55    }};
56}