spl_discriminator/
discriminator.rs1use {
4 bytemuck::{Pod, Zeroable},
5 solana_program_error::ProgramError,
6 solana_sha256_hasher::hashv,
7};
8
9pub trait SplDiscriminate {
11 const SPL_DISCRIMINATOR: ArrayDiscriminator;
13 const SPL_DISCRIMINATOR_SLICE: &'static [u8] = Self::SPL_DISCRIMINATOR.as_slice();
15}
16
17#[cfg_attr(
19 feature = "borsh",
20 derive(borsh::BorshSerialize, borsh::BorshDeserialize)
21)]
22#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
23#[repr(transparent)]
24pub struct ArrayDiscriminator([u8; ArrayDiscriminator::LENGTH]);
25impl ArrayDiscriminator {
26 pub const LENGTH: usize = 8;
28 pub const UNINITIALIZED: Self = Self::new([0; Self::LENGTH]);
30 pub const fn new(value: [u8; Self::LENGTH]) -> Self {
32 Self(value)
33 }
34 pub const fn as_slice(&self) -> &[u8] {
36 self.0.as_slice()
37 }
38 pub fn new_with_hash_input(hash_input: &str) -> Self {
40 let hash_bytes = hashv(&[hash_input.as_bytes()]).to_bytes();
41 let mut discriminator_bytes = [0u8; 8];
42 discriminator_bytes.copy_from_slice(&hash_bytes[..8]);
43 Self(discriminator_bytes)
44 }
45}
46impl AsRef<[u8]> for ArrayDiscriminator {
47 fn as_ref(&self) -> &[u8] {
48 &self.0[..]
49 }
50}
51impl AsRef<[u8; ArrayDiscriminator::LENGTH]> for ArrayDiscriminator {
52 fn as_ref(&self) -> &[u8; ArrayDiscriminator::LENGTH] {
53 &self.0
54 }
55}
56impl From<u64> for ArrayDiscriminator {
57 fn from(from: u64) -> Self {
58 Self(from.to_le_bytes())
59 }
60}
61impl From<[u8; Self::LENGTH]> for ArrayDiscriminator {
62 fn from(from: [u8; Self::LENGTH]) -> Self {
63 Self(from)
64 }
65}
66impl TryFrom<&[u8]> for ArrayDiscriminator {
67 type Error = ProgramError;
68 fn try_from(a: &[u8]) -> Result<Self, Self::Error> {
69 <[u8; Self::LENGTH]>::try_from(a)
70 .map(Self::from)
71 .map_err(|_| ProgramError::InvalidAccountData)
72 }
73}
74impl From<ArrayDiscriminator> for [u8; 8] {
75 fn from(from: ArrayDiscriminator) -> Self {
76 from.0
77 }
78}
79impl From<ArrayDiscriminator> for u64 {
80 fn from(from: ArrayDiscriminator) -> Self {
81 u64::from_le_bytes(from.0)
82 }
83}