Skip to main content

light_compressed_account/
pubkey.rs

1#[cfg(feature = "bytemuck-des")]
2use bytemuck::{Pod, Zeroable};
3use light_zero_copy::{
4    errors::ZeroCopyError,
5    traits::{ZeroCopyAt, ZeroCopyAtMut, ZeroCopyStructInner, ZeroCopyStructInnerMut},
6    ZeroCopyNew,
7};
8use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
9
10#[cfg(feature = "bytemuck-des")]
11#[cfg_attr(
12    all(feature = "std", feature = "anchor"),
13    derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
14)]
15#[cfg_attr(
16    not(feature = "anchor"),
17    derive(borsh::BorshDeserialize, borsh::BorshSerialize)
18)]
19#[derive(
20    Pod,
21    Zeroable,
22    Debug,
23    Copy,
24    PartialEq,
25    Eq,
26    Hash,
27    Clone,
28    Immutable,
29    FromBytes,
30    IntoBytes,
31    KnownLayout,
32    Default,
33    Unaligned,
34)]
35#[repr(C)]
36pub struct Pubkey(pub(crate) [u8; 32]);
37
38#[cfg(not(feature = "bytemuck-des"))]
39#[cfg_attr(
40    all(feature = "std", feature = "anchor"),
41    derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
42)]
43#[cfg_attr(
44    not(feature = "anchor"),
45    derive(borsh::BorshDeserialize, borsh::BorshSerialize)
46)]
47#[derive(
48    Debug,
49    Copy,
50    PartialEq,
51    Eq,
52    Hash,
53    Clone,
54    Immutable,
55    FromBytes,
56    IntoBytes,
57    KnownLayout,
58    Default,
59    Unaligned,
60)]
61#[repr(C)]
62pub struct Pubkey(pub(crate) [u8; 32]);
63
64impl<'a> ZeroCopyNew<'a> for Pubkey {
65    type ZeroCopyConfig = ();
66    type Output = <Self as ZeroCopyAtMut<'a>>::ZeroCopyAtMut;
67    fn byte_len(_config: &Self::ZeroCopyConfig) -> Result<usize, ZeroCopyError> {
68        Ok(32)
69    }
70    fn new_zero_copy(
71        bytes: &'a mut [u8],
72        _config: Self::ZeroCopyConfig,
73    ) -> Result<(Self::Output, &'a mut [u8]), ZeroCopyError> {
74        <Self as ZeroCopyAtMut<'a>>::zero_copy_at_mut(bytes)
75    }
76}
77
78impl Pubkey {
79    pub fn new_from_array(array: [u8; 32]) -> Self {
80        Self(array)
81    }
82
83    pub fn new_from_slice(slice: &[u8]) -> Self {
84        let mut array = [0u8; 32];
85        array.copy_from_slice(slice);
86        Self(array)
87    }
88
89    pub fn array_ref(&self) -> &[u8; 32] {
90        &self.0
91    }
92}
93
94impl AsRef<Pubkey> for Pubkey {
95    fn as_ref(&self) -> &Self {
96        self
97    }
98}
99
100impl AsRef<[u8]> for Pubkey {
101    fn as_ref(&self) -> &[u8] {
102        &self.0
103    }
104}
105
106impl PartialEq<[u8; 32]> for Pubkey {
107    fn eq(&self, other: &[u8; 32]) -> bool {
108        self.0 == *other
109    }
110}
111
112#[cfg(feature = "anchor")]
113impl PartialEq<anchor_lang::prelude::Pubkey> for Pubkey {
114    fn eq(&self, other: &anchor_lang::prelude::Pubkey) -> bool {
115        self.0 == other.to_bytes()
116    }
117}
118
119impl<'a> ZeroCopyAt<'a> for Pubkey {
120    type ZeroCopyAt = Ref<&'a [u8], Pubkey>;
121
122    #[inline]
123    fn zero_copy_at(bytes: &'a [u8]) -> Result<(Ref<&'a [u8], Pubkey>, &'a [u8]), ZeroCopyError> {
124        Ok(Ref::<&[u8], Pubkey>::from_prefix(bytes)?)
125    }
126}
127
128impl<'a> ZeroCopyAtMut<'a> for Pubkey {
129    type ZeroCopyAtMut = Ref<&'a mut [u8], Pubkey>;
130
131    #[inline]
132    fn zero_copy_at_mut(
133        bytes: &'a mut [u8],
134    ) -> Result<(Self::ZeroCopyAtMut, &'a mut [u8]), ZeroCopyError> {
135        Ok(Ref::<&mut [u8], Pubkey>::from_prefix(bytes)?)
136    }
137}
138
139impl ZeroCopyStructInner for Pubkey {
140    type ZeroCopyInner = Pubkey;
141}
142
143impl ZeroCopyStructInnerMut for Pubkey {
144    type ZeroCopyInnerMut = Pubkey;
145}
146impl From<Pubkey> for [u8; 32] {
147    fn from(pubkey: Pubkey) -> Self {
148        pubkey.to_bytes()
149    }
150}
151
152impl From<&Pubkey> for [u8; 32] {
153    fn from(pubkey: &Pubkey) -> Self {
154        pubkey.to_bytes()
155    }
156}
157
158impl From<[u8; 32]> for Pubkey {
159    fn from(pubkey: [u8; 32]) -> Self {
160        Self(pubkey)
161    }
162}
163
164impl From<&[u8; 32]> for Pubkey {
165    fn from(pubkey: &[u8; 32]) -> Self {
166        Self(*pubkey)
167    }
168}
169
170#[cfg(feature = "anchor")]
171impl From<&anchor_lang::prelude::Pubkey> for Pubkey {
172    fn from(pubkey: &anchor_lang::prelude::Pubkey) -> Self {
173        Self::new_from_array(pubkey.to_bytes())
174    }
175}
176
177#[cfg(feature = "anchor")]
178impl From<anchor_lang::prelude::Pubkey> for Pubkey {
179    fn from(pubkey: anchor_lang::prelude::Pubkey) -> Self {
180        Self::new_from_array(pubkey.to_bytes())
181    }
182}
183
184#[cfg(feature = "anchor")]
185impl From<Pubkey> for anchor_lang::prelude::Pubkey {
186    fn from(pubkey: Pubkey) -> Self {
187        Self::new_from_array(pubkey.to_bytes())
188    }
189}
190
191#[cfg(feature = "anchor")]
192impl From<&Pubkey> for anchor_lang::prelude::Pubkey {
193    fn from(pubkey: &Pubkey) -> Self {
194        Self::new_from_array(pubkey.to_bytes())
195    }
196}
197
198impl Pubkey {
199    #[cfg(feature = "new-unique")]
200    pub fn new_unique() -> Self {
201        Self(solana_pubkey::Pubkey::new_unique().to_bytes())
202    }
203
204    pub fn to_bytes(&self) -> [u8; 32] {
205        self.0
206    }
207}
208
209pub trait AsPubkey {
210    fn to_pubkey_bytes(&self) -> [u8; 32];
211    #[cfg(feature = "anchor")]
212    fn to_anchor_pubkey(&self) -> anchor_lang::prelude::Pubkey;
213    fn to_light_pubkey(&self) -> Pubkey {
214        self.to_pubkey_bytes().into()
215    }
216}
217
218impl AsPubkey for Pubkey {
219    fn to_pubkey_bytes(&self) -> [u8; 32] {
220        self.to_bytes()
221    }
222    #[cfg(feature = "anchor")]
223    fn to_anchor_pubkey(&self) -> anchor_lang::prelude::Pubkey {
224        self.into()
225    }
226    fn to_light_pubkey(&self) -> Pubkey {
227        *self
228    }
229}
230
231#[cfg(feature = "anchor")]
232impl AsPubkey for anchor_lang::prelude::Pubkey {
233    fn to_pubkey_bytes(&self) -> [u8; 32] {
234        self.to_bytes()
235    }
236
237    #[cfg(feature = "anchor")]
238    fn to_anchor_pubkey(&self) -> Self {
239        *self
240    }
241}
242
243#[cfg(all(feature = "solana", not(feature = "anchor")))]
244impl AsPubkey for solana_pubkey::Pubkey {
245    fn to_pubkey_bytes(&self) -> [u8; 32] {
246        self.to_bytes()
247    }
248}
249
250impl AsPubkey for [u8; 32] {
251    fn to_pubkey_bytes(&self) -> [u8; 32] {
252        *self
253    }
254    #[cfg(feature = "anchor")]
255    fn to_anchor_pubkey(&self) -> anchor_lang::prelude::Pubkey {
256        (*self).into()
257    }
258}