Skip to main content

typhoon_traits/account/
wincode.rs

1use {
2    crate::{Accessor, MutAccessor, Write},
3    core::marker::PhantomData,
4    solana_program_error::ProgramError,
5    wincode::{
6        config::{ConfigCore, Configuration, DefaultConfig, DEFAULT_PREALLOCATION_SIZE_LIMIT},
7        len::UseIntLen,
8        SchemaRead, SchemaWrite,
9    },
10};
11
12pub type BorshConfig = Configuration<true, DEFAULT_PREALLOCATION_SIZE_LIMIT, UseIntLen<u32>>;
13
14pub type BorshStrategy<const ZERO_COPY: bool> = WincodeStrategy<ZERO_COPY, BorshConfig>;
15
16pub struct WincodeStrategy<const ZERO_COPY: bool, C = DefaultConfig>(PhantomData<C>);
17
18impl<'a, T: 'a, C> Accessor<'a, T> for WincodeStrategy<true, C>
19where
20    C: ConfigCore,
21    &'a T: SchemaRead<'a, C, Dst = &'a T>,
22{
23    type Data = &'a T;
24
25    #[inline(always)]
26    fn access(data: &'a [u8]) -> Result<Self::Data, ProgramError> {
27        <&T as SchemaRead<'a, C>>::get(data).map_err(|_| ProgramError::BorshIoError)
28    }
29
30    #[inline(always)]
31    fn read(data: &mut &'a [u8]) -> Result<Self::Data, ProgramError> {
32        <&T as SchemaRead<'a, C>>::get(data).map_err(|_| ProgramError::BorshIoError)
33    }
34}
35
36impl<'a, T, C> Accessor<'a, T> for WincodeStrategy<false, C>
37where
38    C: ConfigCore,
39    T: SchemaRead<'a, C, Dst = T> + 'a,
40{
41    type Data = T;
42
43    #[inline(always)]
44    fn access(data: &'a [u8]) -> Result<Self::Data, ProgramError> {
45        <T as SchemaRead<'a, C>>::get(data).map_err(|_| ProgramError::BorshIoError)
46    }
47
48    #[inline(always)]
49    fn read(data: &mut &'a [u8]) -> Result<Self::Data, ProgramError> {
50        <T as SchemaRead<'a, C>>::get(data).map_err(|_| ProgramError::BorshIoError)
51    }
52}
53
54impl<'a, T: 'a, C> MutAccessor<'a, T> for WincodeStrategy<true, C>
55where
56    C: ConfigCore,
57    &'a mut T: SchemaRead<'a, C, Dst = &'a mut T>,
58{
59    type Data = &'a mut T;
60
61    #[inline(always)]
62    fn access_mut(data: &'a mut [u8]) -> Result<Self::Data, ProgramError> {
63        <&mut T as SchemaRead<'a, C>>::get(data).map_err(|_| ProgramError::InvalidAccountData)
64    }
65}
66
67impl<T, const ZERO_COPY: bool, C> Write<T> for WincodeStrategy<ZERO_COPY, C>
68where
69    C: ConfigCore,
70    T: SchemaWrite<C, Src = T>,
71{
72    #[inline(always)]
73    fn write_into(writer: impl wincode::io::Writer, data: &T) -> Result<(), ProgramError> {
74        T::write(writer, data).map_err(|_| ProgramError::BorshIoError)
75    }
76
77    #[inline(always)]
78    fn size(data: &T) -> Result<usize, ProgramError> {
79        T::size_of(data).map_err(|_| ProgramError::BorshIoError)
80    }
81}