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