1use std::borrow::Cow;
2
3use anchor_lang::{err, Discriminator};
4
5pub fn check_discriminator<T: Discriminator>(data: &[u8]) -> anchor_lang::prelude::Result<()> {
7 use anchor_lang::error::ErrorCode;
8
9 let disc = T::discriminator();
10 if data.len() < disc.len() {
11 return err!(ErrorCode::AccountDiscriminatorNotFound);
12 }
13 let given_disc = &data[..8];
14 if disc != given_disc {
15 return err!(ErrorCode::AccountDiscriminatorMismatch);
16 }
17 Ok(())
18}
19
20pub fn try_deserailize<T>(data: &[u8]) -> anchor_lang::prelude::Result<T>
24where
25 T: anchor_lang::ZeroCopy,
26{
27 check_discriminator::<T>(data)?;
28 try_deserailize_unchecked(data)
29}
30
31pub fn try_deserailize_unchecked<T>(data: &[u8]) -> anchor_lang::prelude::Result<T>
35where
36 T: anchor_lang::ZeroCopy,
37{
38 use anchor_lang::{error, error::ErrorCode};
39 let end = std::mem::size_of::<T>() + 8;
40 if data.len() < end {
41 return err!(ErrorCode::AccountDidNotDeserialize);
42 }
43 let mut data_without_discriminator = Cow::Borrowed(&data[8..end]);
45 Ok(
46 *bytemuck::try_from_bytes(data_without_discriminator.to_mut())
47 .map_err(|_| error!(ErrorCode::AccountDidNotDeserialize))?,
48 )
49}