From 883dc606e9c72896ce1e44d7af6e5770acb86bef Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Tue, 3 Mar 2026 09:24:18 +0100 Subject: [PATCH 1/2] pod: wincode support for PodOption --- pod/src/option.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pod/src/option.rs b/pod/src/option.rs index ad5004d..a35277c 100644 --- a/pod/src/option.rs +++ b/pod/src/option.rs @@ -10,6 +10,8 @@ use bytemuck::{Pod, Zeroable}; #[cfg(feature = "serde")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "wincode")] +use wincode_derive::{SchemaRead, SchemaWrite}; #[cfg(feature = "borsh")] use { alloc::format, @@ -50,6 +52,7 @@ pub trait Nullable: PartialEq + Sized { feature = "borsh", derive(BorshDeserialize, BorshSerialize, BorshSchema) )] +#[cfg_attr(feature = "wincode", derive(SchemaRead, SchemaWrite))] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct PodOption(T); @@ -326,6 +329,46 @@ mod tests { } } + #[cfg(feature = "wincode")] + mod wincode_tests { + use {super::*, alloc::vec, alloc::vec::Vec}; + + fn serialize(value: &T) -> Vec + where + T: wincode::SchemaWrite, + { + let size = wincode::serialized_size(value).unwrap() as usize; + let mut bytes = vec![0u8; size]; + wincode::serialize_into(&mut bytes[..], value).unwrap(); + bytes + } + + #[test] + fn test_wincode_pod_option_roundtrip_and_size() { + let some = PodOption::from(9u64); + let none = PodOption::from(0u64); + + let some_bytes = serialize(&some); + let none_bytes = serialize(&none); + + assert_eq!(some_bytes.len(), core::mem::size_of::()); + assert_eq!(none_bytes.len(), core::mem::size_of::()); + assert_eq!(some_bytes.as_slice(), &9u64.to_le_bytes()); + assert_eq!(none_bytes.as_slice(), &0u64.to_le_bytes()); + + let some_roundtrip: PodOption = wincode::deserialize(&some_bytes).unwrap(); + let none_roundtrip: PodOption = wincode::deserialize(&none_bytes).unwrap(); + assert_eq!(some_roundtrip, some); + assert_eq!(none_roundtrip, none); + } + + #[test] + fn test_wincode_pod_option_rejects_truncated_input() { + assert!(wincode::deserialize::>(&[]).is_err()); + assert!(wincode::deserialize::>(&[0; 7]).is_err()); + } + } + #[cfg(feature = "serde")] mod serde_tests { use {super::*, alloc::string::ToString}; From 22879815078c21895c9f7a2458d6449d355c9db1 Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Tue, 3 Mar 2026 11:38:43 +0100 Subject: [PATCH 2/2] Review updates --- pod/Cargo.toml | 1 + pod/src/option.rs | 16 +++------------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/pod/Cargo.toml b/pod/Cargo.toml index f0928a7..18edb2a 100644 --- a/pod/Cargo.toml +++ b/pod/Cargo.toml @@ -29,6 +29,7 @@ wincode-derive = { version = "0.4.2", optional = true } serde_json = "1.0.145" spl-pod = { path = ".", features = ["bytemuck", "wincode", "borsh"] } test-case = "3.3.1" +wincode = { version = "0.4.4", default-features = false, features = ["alloc"] } [lib] crate-type = ["lib"] diff --git a/pod/src/option.rs b/pod/src/option.rs index a35277c..0a080ec 100644 --- a/pod/src/option.rs +++ b/pod/src/option.rs @@ -331,25 +331,15 @@ mod tests { #[cfg(feature = "wincode")] mod wincode_tests { - use {super::*, alloc::vec, alloc::vec::Vec}; - - fn serialize(value: &T) -> Vec - where - T: wincode::SchemaWrite, - { - let size = wincode::serialized_size(value).unwrap() as usize; - let mut bytes = vec![0u8; size]; - wincode::serialize_into(&mut bytes[..], value).unwrap(); - bytes - } + use super::*; #[test] fn test_wincode_pod_option_roundtrip_and_size() { let some = PodOption::from(9u64); let none = PodOption::from(0u64); - let some_bytes = serialize(&some); - let none_bytes = serialize(&none); + let some_bytes = wincode::serialize(&some).unwrap(); + let none_bytes = wincode::serialize(&none).unwrap(); assert_eq!(some_bytes.len(), core::mem::size_of::()); assert_eq!(none_bytes.len(), core::mem::size_of::());