Skip to content

Commit

Permalink
instruction: Add no-alloc helper for instruction data (#4)
Browse files Browse the repository at this point in the history
* instruction: Add no-alloc helper for instruction data

#### Problem

Constructing instruction data requires using a serialization library
such as bincode or borsh, but it's much simpler to create an instance of
the instruction and just reinterpret those bytes (assuming the type is a
properly packed struct).

#### Summary of changes

Add a helper for creating a type used for instruction data.

* Bump patch version
  • Loading branch information
joncinque authored Nov 2, 2024
1 parent b658f47 commit 87d40df
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ You can run the convenience script in this repo to download the compiler to
1. Add this package to your project:

```console
zig fetch --save https://github.com/joncinque/solana-program-sdk-zig/archive/refs/tags/v0.14.0.tar.gz
zig fetch --save https://github.com/joncinque/solana-program-sdk-zig/archive/refs/tags/v0.14.1.tar.gz
```

2. (Optional) if you want to generate a keypair during building, you'll also
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.{
.name = "solana-program-sdk",
.version = "0.14.0",
.version = "0.14.1",
.minimum_zig_version = "0.13.0",

// This field is optional.
Expand Down
29 changes: 29 additions & 0 deletions src/instruction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,32 @@ pub const Instruction = extern struct {
return error.CrossProgramInvocationFailed;
}
};

/// Helper for no-alloc CPIs. By providing a discriminant and data type, the
/// dynamic type can be constructed in-place and used for instruction data:
///
/// const Discriminant = enum(u32) {
/// one,
/// };
/// const Data = packed struct {
/// field: u64
/// };
/// const data = InstructionData(Discriminant, Data) {
/// .discriminant = Discriminant.one,
/// .data = .{ .field = 1 }
/// };
/// const instruction = Instruction.from(.{
/// .program_id = ...,
/// .accounts = &[_]Account.Param{...},
/// .data = data.asBytes(),
/// });
pub fn InstructionData(comptime Discriminant: type, comptime Data: type) type {
return packed struct {
discriminant: Discriminant,
data: Data,
const Self = @This();
fn asBytes(self: *const Self) []const u8 {
return std.mem.asBytes(self)[0..(@sizeOf(Discriminant) + @sizeOf(Data))];
}
};
}

0 comments on commit 87d40df

Please sign in to comment.