Skip to main content

segmented_interface

Macro segmented_interface 

Source
macro_rules! segmented_interface {
    (
        $(#[$meta:meta])*
        $vis:vis struct $name:ident for $owner:path {
            $( $(#[$fmeta:meta])* $field:ident : $fty:ident = $fsize:expr ),+ $(,)?
        } segments {
            $( $seg_name:ident : $seg_ty:ident = $seg_elem_size:expr ),+ $(,)?
        }
    ) => { ... };
    (
        $(#[$meta:meta])*
        $vis:vis struct $name:ident for $owner:path, version = $ver:literal {
            $( $(#[$fmeta:meta])* $field:ident : $fty:ident = $fsize:expr ),+ $(,)?
        } segments {
            $( $seg_name:ident : $seg_ty:ident = $seg_elem_size:expr ),+ $(,)?
        }
    ) => { ... };
    (
        @impl version = $ver:literal,
        $(#[$meta:meta])*
        $vis:vis struct $name:ident for $owner:path {
            $( $(#[$fmeta:meta])* $field:ident : $fty:ident = $fsize:expr ),+ $(,)?
        } segments {
            $( $seg_name:ident : $seg_ty:ident = $seg_elem_size:expr ),+ $(,)?
        }
    ) => { ... };
}
Expand description

Declare a read-only interface for a foreign program’s segmented account.

Extends jiminy_interface! with segment declarations, generating the same SEGMENTED_LAYOUT_ID as the foreign program’s segmented_layout! definition. This enables cross-program reads of variable-length accounts (order books, staking pools, etc.) without crate dependencies.

§Usage

Program B wants to read Program A’s OrderBook segmented account:

use jiminy_core::segmented_interface;
use jiminy_core::account::{AccountHeader, Pod, FixedLayout};
use jiminy_core::abi::LeU64;
use hopper_runtime::Address;

const DEX_PROGRAM: Address = [0u8; 32];

// Order element type (must match Program A's definition)
#[repr(C)]
#[derive(Clone, Copy)]
struct Order {
    price: LeU64,
    size:  LeU64,
}
unsafe impl Pod for Order {}
impl FixedLayout for Order { const SIZE: usize = 16; }

segmented_interface! {
    pub struct OrderBook for DEX_PROGRAM {
        header:  AccountHeader = 16,
        market:  Address       = 32,
    } segments {
        bids: Order = 16,
        asks: Order = 16,
    }
}

// In your instruction handler:
fn process(accounts: &[AccountView]) -> ProgramResult {
    let data = OrderBook::load_foreign_segmented(&accounts[0])?;
    let table = OrderBook::segment_table(&data)?;
    let bids = SegmentSlice::<Order>::from_descriptor(&data, &table.descriptor(0)?)?;
    // read bids...
    Ok(())
}

§What gets generated

Everything from jiminy_interface! plus:

  • SEGMENTED_LAYOUT_ID matching the foreign segmented_layout!
  • SEGMENT_COUNT, TABLE_OFFSET, DATA_START_OFFSET, MIN_ACCOUNT_SIZE
  • segment_table(data): read-only segment table access
  • segment::<T>(data, index): typed read-only segment slice
  • validate_segments(data): full segment validation
  • load_foreign_segmented(account): Tier 2 validation with min-size

No mutable access is generated (consistent with interface philosophy).