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 ad5004d..0a080ec 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,36 @@ mod tests { } } + #[cfg(feature = "wincode")] + mod wincode_tests { + use super::*; + + #[test] + fn test_wincode_pod_option_roundtrip_and_size() { + let some = PodOption::from(9u64); + let none = PodOption::from(0u64); + + 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::()); + 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};