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_IDmatching the foreignsegmented_layout!SEGMENT_COUNT,TABLE_OFFSET,DATA_START_OFFSET,MIN_ACCOUNT_SIZEsegment_table(data): read-only segment table accesssegment::<T>(data, index): typed read-only segment slicevalidate_segments(data): full segment validationload_foreign_segmented(account): Tier 2 validation with min-size
No mutable access is generated (consistent with interface philosophy).