@@ -111,14 +111,26 @@ macro_rules! solitaire {
111
111
112
112
#[ macro_export]
113
113
macro_rules! pack_type_impl {
114
- ( $name: ident, $embed: ty, $owner: expr) => {
114
+ // We take a "unpacker" as an input, which specifies how to unpack the embedded type.
115
+ // In most cases, this should be just be
116
+ // `solana_program::program_pack::Pack`, but in some cases (like token-2022
117
+ // mints) it may be a custom trait that provides an `unpack` method. This is
118
+ // because `Pack` does a strict length check on the account, whereas
119
+ // token-2022 mints with extensions might be longer.
120
+ //
121
+ // NOTE: we only use this on the deserialisation side, but we keep the call for serialisation
122
+ // as solana_program::program_pack::Pack::pack_into_slice. We could generalise that side too, but in
123
+ // reality, that code is never invoked, because solitaire will persist (and
124
+ // thus serialise) accounts that are owned by the current program.
125
+ // `pack_type!` on the other hands is only used for solitaire-ising external accounts.
126
+ ( $name: ident, $embed: ty, $owner: expr, $unpacker: path) => {
115
127
#[ repr( transparent) ]
116
128
pub struct $name( pub $embed) ;
117
129
118
130
impl BorshDeserialize for $name {
119
131
fn deserialize( buf: & mut & [ u8 ] ) -> std:: io:: Result <Self > {
120
132
let acc = $name(
121
- solana_program :: program_pack :: Pack :: unpack( buf)
133
+ <$embed as $unpacker> :: unpack( buf)
122
134
. map_err( |e| std:: io:: Error :: new( std:: io:: ErrorKind :: Other , e) ) ?,
123
135
) ;
124
136
// We need to clear the buf to show to Borsh that we've read all data
@@ -162,15 +174,21 @@ macro_rules! pack_type_impl {
162
174
#[ macro_export]
163
175
macro_rules! pack_type {
164
176
( $name: ident, $embed: ty, AccountOwner :: OneOf ( $owner: expr) ) => {
165
- solitaire:: pack_type_impl!( $name, $embed, AccountOwner :: OneOf ( $owner) ) ;
177
+ solitaire:: pack_type_impl!( $name, $embed, AccountOwner :: OneOf ( $owner) , solana_program :: program_pack :: Pack ) ;
166
178
167
179
impl solitaire:: processors:: seeded:: MultiOwned for $name {
168
180
}
169
181
} ;
170
182
( $name: ident, $embed: ty, $owner: expr) => {
171
- solitaire:: pack_type_impl!( $name, $embed, $owner) ;
183
+ solitaire:: pack_type_impl!( $name, $embed, $owner, solana_program :: program_pack :: Pack ) ;
172
184
173
185
impl solitaire:: processors:: seeded:: SingleOwned for $name {
174
186
}
175
187
} ;
188
+ ( $name: ident, $embed: ty, AccountOwner :: OneOf ( $owner: expr) , $unpacker: ident) => {
189
+ solitaire:: pack_type_impl!( $name, $embed, AccountOwner :: OneOf ( $owner) , $unpacker) ;
190
+
191
+ impl solitaire:: processors:: seeded:: MultiOwned for $name {
192
+ }
193
+ } ;
176
194
}
0 commit comments