Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit db5eaa7

Browse files
authored
Move Pod types to separate library (#5119)
* Move Pod types to separate library - just move code * Move Pod types to separate library - add/modify logic and tests * Move Pod types to separate library - small test changes * Move Pod types to separate library - small test changes * Move Pod types to separate library - small test changes --------- Co-authored-by: Serban <@>
1 parent 4523983 commit db5eaa7

File tree

57 files changed

+990
-726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+990
-726
lines changed

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ members = [
2626
"libraries/concurrent-merkle-tree",
2727
"libraries/math",
2828
"libraries/merkle-tree-reference",
29+
"libraries/pod",
2930
"libraries/program-error",
3031
"libraries/tlv-account-resolution",
3132
"libraries/type-length-value",

libraries/pod/Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "spl-pod"
3+
version = "0.1.0"
4+
description = "Solana Program Library Plain Old Data (Pod)"
5+
authors = ["Solana Labs Maintainers <[email protected]>"]
6+
repository = "https://github.com/solana-labs/solana-program-library"
7+
license = "Apache-2.0"
8+
edition = "2021"
9+
10+
[features]
11+
serde-traits = ["serde", "base64"]
12+
borsh = ["dep:borsh"]
13+
14+
[dependencies]
15+
base64 = { version = "0.21.2", optional = true }
16+
borsh = { version = "0.10", optional = true }
17+
bytemuck = { version = "1.13.1" }
18+
serde = { version = "1.0.183", optional = true }
19+
solana-program = "1.16.3"
20+
solana-zk-token-sdk = "1.16.3"
21+
spl-program-error = { version = "0.2.0", path = "../program-error" }
22+
23+
[dev-dependencies]
24+
serde_json = "1.0.105"
25+
26+
[lib]
27+
crate-type = ["cdylib", "lib"]
28+
29+
[package.metadata.docs.rs]
30+
targets = ["x86_64-unknown-linux-gnu"]

libraries/pod/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Pod
2+
3+
This library contains types shared by SPL libraries that implement the `Pod` trait from `bytemuck` and utils for working with these types.

libraries/pod/src/bytemuck.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! wrappers for bytemuck functions
2+
3+
use {bytemuck::Pod, solana_program::program_error::ProgramError};
4+
5+
/// On-chain size of a `Pod` type
6+
pub const fn pod_get_packed_len<T: Pod>() -> usize {
7+
std::mem::size_of::<T>()
8+
}
9+
10+
/// Convert a `Pod` into a slice (zero copy)
11+
pub fn pod_bytes_of<T: Pod>(t: &T) -> &[u8] {
12+
bytemuck::bytes_of(t)
13+
}
14+
15+
/// Convert a slice into a `Pod` (zero copy)
16+
pub fn pod_from_bytes<T: Pod>(bytes: &[u8]) -> Result<&T, ProgramError> {
17+
bytemuck::try_from_bytes(bytes).map_err(|_| ProgramError::InvalidArgument)
18+
}
19+
20+
/// Maybe convert a slice into a `Pod` (zero copy)
21+
///
22+
/// Returns `None` if the slice is empty, but `Err` if all other lengths but `get_packed_len()`
23+
/// This function exists primarily because `Option<T>` is not a `Pod`.
24+
pub fn pod_maybe_from_bytes<T: Pod>(bytes: &[u8]) -> Result<Option<&T>, ProgramError> {
25+
if bytes.is_empty() {
26+
Ok(None)
27+
} else {
28+
bytemuck::try_from_bytes(bytes)
29+
.map(Some)
30+
.map_err(|_| ProgramError::InvalidArgument)
31+
}
32+
}
33+
34+
/// Convert a slice into a mutable `Pod` (zero copy)
35+
pub fn pod_from_bytes_mut<T: Pod>(bytes: &mut [u8]) -> Result<&mut T, ProgramError> {
36+
bytemuck::try_from_bytes_mut(bytes).map_err(|_| ProgramError::InvalidArgument)
37+
}
38+
39+
/// Convert a slice into a mutable `Pod` slice (zero copy)
40+
pub fn pod_slice_from_bytes<T: Pod>(bytes: &[u8]) -> Result<&[T], ProgramError> {
41+
bytemuck::try_cast_slice(bytes).map_err(|_| ProgramError::InvalidArgument)
42+
}
43+
44+
/// Convert a slice into a mutable `Pod` slice (zero copy)
45+
pub fn pod_slice_from_bytes_mut<T: Pod>(bytes: &mut [u8]) -> Result<&mut [T], ProgramError> {
46+
bytemuck::try_cast_slice_mut(bytes).map_err(|_| ProgramError::InvalidArgument)
47+
}
48+
49+
/// Convert a pod slice into its raw bytes
50+
pub fn pod_slice_to_bytes<T: Pod>(slice: &[T]) -> &[u8] {
51+
bytemuck::cast_slice(slice)
52+
}

libraries/pod/src/error.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! Error types
2+
use spl_program_error::*;
3+
4+
/// Errors that may be returned by the spl-pod library.
5+
#[spl_program_error]
6+
pub enum PodSliceError {
7+
/// Error in checked math operation
8+
#[error("Error in checked math operation")]
9+
CalculationFailure,
10+
/// Provided byte buffer too small for expected type
11+
#[error("Provided byte buffer too small for expected type")]
12+
BufferTooSmall,
13+
/// Provided byte buffer too large for expected type
14+
#[error("Provided byte buffer too large for expected type")]
15+
BufferTooLarge,
16+
}

libraries/pod/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! Crate containing `Pod` types and `bytemuck` utils used in SPL
2+
3+
pub mod bytemuck;
4+
pub mod error;
5+
pub mod optional_keys;
6+
pub mod primitives;
7+
pub mod slice;
8+
9+
// Export current sdk types for downstream users building with a different sdk
10+
// version
11+
pub use solana_program;

0 commit comments

Comments
 (0)