From cb7b83ede505cb92ded21f4f8829450d2a6079f6 Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Thu, 26 Feb 2026 12:17:06 +0100 Subject: [PATCH 1/2] no-std spl-pod # Conflicts: # pod/Cargo.toml # pod/src/lib.rs # pod/src/primitives.rs --- Cargo.lock | 4 ++-- pod/Cargo.toml | 2 +- pod/src/lib.rs | 5 +++++ pod/src/optional_keys.rs | 2 ++ pod/src/primitives.rs | 5 +++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae4b336..6b34a7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1319,9 +1319,9 @@ dependencies = [ [[package]] name = "solana-program-option" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e7b4ddb464f274deb4a497712664c3b612e3f5f82471d4e47710fc4ab1c3095" +checksum = "362279f6e8020e4cf11313233789bf619420ad8835ebc91963ee5cec91bb05da" [[package]] name = "solana-program-pack" diff --git a/pod/Cargo.toml b/pod/Cargo.toml index 722a924..3645b0f 100644 --- a/pod/Cargo.toml +++ b/pod/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" bytemuck = ["dep:bytemuck", "dep:bytemuck_derive", "solana-address/bytemuck"] serde = ["dep:serde", "solana-address/decode"] borsh = ["dep:borsh", "solana-address/borsh"] -wincode = ["dep:wincode"] +wincode = ["dep:wincode", "wincode/alloc"] [dependencies] borsh = { version = "1.5.7", features = ["derive", "unstable__schema"], optional = true } diff --git a/pod/src/lib.rs b/pod/src/lib.rs index a76f64e..bdba2f1 100644 --- a/pod/src/lib.rs +++ b/pod/src/lib.rs @@ -1,5 +1,10 @@ +#![cfg_attr(not(test), no_std)] + //! Crate containing `Pod` types and `bytemuck` utilities used in SPL +#[cfg(any(feature = "borsh", feature = "serde", feature = "wincode"))] +extern crate alloc; + #[cfg(feature = "bytemuck")] pub mod bytemuck; pub mod option; diff --git a/pod/src/optional_keys.rs b/pod/src/optional_keys.rs index 49c26c0..ed5c569 100644 --- a/pod/src/optional_keys.rs +++ b/pod/src/optional_keys.rs @@ -1,4 +1,6 @@ //! Optional addresses that can be used a `Pod`s +#[cfg(any(feature = "borsh", feature = "serde"))] +use alloc::string::ToString; #[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; #[cfg(feature = "bytemuck")] diff --git a/pod/src/primitives.rs b/pod/src/primitives.rs index 5a088fe..8359230 100644 --- a/pod/src/primitives.rs +++ b/pod/src/primitives.rs @@ -7,6 +7,11 @@ use bytemuck_derive::{Pod, Zeroable}; use serde::{Deserialize, Serialize}; #[cfg(feature = "wincode")] use wincode::{SchemaRead, SchemaWrite}; +#[cfg(feature = "borsh")] +use { + alloc::string::ToString, + borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, +}; /// The standard `bool` is not a `Pod`, define a replacement that is #[cfg_attr(feature = "wincode", derive(SchemaRead, SchemaWrite))] From 5f5f85a228bafe6bc0c0a6f051de3ea4f82fc386 Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Thu, 26 Feb 2026 18:22:32 +0100 Subject: [PATCH 2/2] pr review feedback --- Cargo.lock | 2 ++ pod/Cargo.toml | 12 +++++++----- pod/src/lib.rs | 4 ++-- pod/src/option.rs | 2 +- pod/src/primitives.rs | 17 ++++++++--------- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b34a7e..96c8aa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1663,6 +1663,7 @@ dependencies = [ "bytemuck", "bytemuck_derive", "serde", + "serde_derive", "serde_json", "solana-address 2.2.0", "solana-program-error", @@ -1670,6 +1671,7 @@ dependencies = [ "spl-pod 0.7.2", "test-case", "wincode", + "wincode-derive", ] [[package]] diff --git a/pod/Cargo.toml b/pod/Cargo.toml index 3645b0f..66b76e8 100644 --- a/pod/Cargo.toml +++ b/pod/Cargo.toml @@ -9,19 +9,21 @@ edition = "2021" [features] bytemuck = ["dep:bytemuck", "dep:bytemuck_derive", "solana-address/bytemuck"] -serde = ["dep:serde", "solana-address/decode"] +serde = ["dep:serde", "dep:serde_derive", "solana-address/decode"] borsh = ["dep:borsh", "solana-address/borsh"] -wincode = ["dep:wincode", "wincode/alloc"] +wincode = ["dep:wincode", "dep:wincode-derive"] [dependencies] -borsh = { version = "1.5.7", features = ["derive", "unstable__schema"], optional = true } +borsh = { version = "1.5.7", default-features = false, features = ["derive", "unstable__schema"], optional = true } bytemuck = { version = "1.23.2", optional = true } bytemuck_derive = { version = "1.10.1", optional = true } -serde = { version = "1.0.228", optional = true, features = ["derive"] } +serde = { version = "1.0.228", default-features = false, optional = true, features = ["alloc"] } +serde_derive = { version = "1.0.228", optional = true } solana-address = { version = "2.2.0", features = ["copy"] } solana-program-error = "3.0.0" solana-program-option = "3.0.0" -wincode = { version = "0.4.4", features = ["derive"], optional = true } +wincode = { version = "0.4.4", default-features = false, optional = true } +wincode-derive = { version = "0.4.2", optional = true } [dev-dependencies] base64 = { version = "0.22.1" } diff --git a/pod/src/lib.rs b/pod/src/lib.rs index bdba2f1..3f1be8f 100644 --- a/pod/src/lib.rs +++ b/pod/src/lib.rs @@ -1,8 +1,8 @@ -#![cfg_attr(not(test), no_std)] +#![no_std] //! Crate containing `Pod` types and `bytemuck` utilities used in SPL -#[cfg(any(feature = "borsh", feature = "serde", feature = "wincode"))] +#[cfg(any(feature = "borsh", feature = "serde", test))] extern crate alloc; #[cfg(feature = "bytemuck")] diff --git a/pod/src/option.rs b/pod/src/option.rs index 9b222e6..43802ce 100644 --- a/pod/src/option.rs +++ b/pod/src/option.rs @@ -149,9 +149,9 @@ impl Nullable for Address { #[cfg(test)] mod tests { - use super::*; #[cfg(feature = "bytemuck")] use crate::bytemuck::pod_slice_from_bytes; + use {super::*, alloc::vec::Vec}; const ID: Address = Address::from_str_const("TestSysvar111111111111111111111111111111111"); #[cfg(feature = "bytemuck")] diff --git a/pod/src/primitives.rs b/pod/src/primitives.rs index 8359230..6f841b3 100644 --- a/pod/src/primitives.rs +++ b/pod/src/primitives.rs @@ -1,12 +1,10 @@ //! primitive types that can be used in `Pod`s -#[cfg(feature = "borsh")] -use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; #[cfg(feature = "bytemuck")] use bytemuck_derive::{Pod, Zeroable}; #[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use serde_derive::{Deserialize, Serialize}; #[cfg(feature = "wincode")] -use wincode::{SchemaRead, SchemaWrite}; +use wincode_derive::{SchemaRead, SchemaWrite}; #[cfg(feature = "borsh")] use { alloc::string::ToString, @@ -250,9 +248,6 @@ mod tests { #[test] fn test_pod_i16_serde() { let pod_i16: PodI16 = i16::MAX.into(); - - println!("pod_i16 {:?}", pod_i16); - let serialized = serde_json::to_string(&pod_i16).unwrap(); assert_eq!(&serialized, "32767"); @@ -376,8 +371,12 @@ mod tests { >( pod: T, ) { - let bytes = wincode::serialize(&pod).unwrap(); - let deserialized: T = wincode::deserialize(&bytes).unwrap(); + let size = wincode::serialized_size(&pod).unwrap() as usize; + let mut bytes = [0u8; 32]; + assert!(size <= bytes.len()); + wincode::serialize_into(&mut bytes[..size], &pod).unwrap(); + + let deserialized: T = wincode::deserialize(&bytes[..size]).unwrap(); assert_eq!(pod, deserialized); } }