dlp_api/compact/
account_meta.rs1use borsh::{
2 io::{Read, Write},
3 BorshDeserialize, BorshSerialize,
4};
5use serde::{Deserialize, Serialize};
6
7use crate::{args::MaybeEncryptedAccountMeta, compact::ClearText};
8
9const ACCOUNT_INDEX_MASK: u8 = 0b0011_1111;
10const SIGNER_MASK: u8 = 0b0100_0000;
11const WRITABLE_MASK: u8 = 0b1000_0000;
12
13pub const MAX_PUBKEYS: u8 = ACCOUNT_INDEX_MASK + 1;
17
18#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
22pub struct AccountMeta(u8);
23
24impl BorshSerialize for AccountMeta {
25 fn serialize<W: Write>(
26 &self,
27 writer: &mut W,
28 ) -> Result<(), borsh::io::Error> {
29 BorshSerialize::serialize(&self.0, writer)
30 }
31}
32
33impl BorshDeserialize for AccountMeta {
34 fn deserialize_reader<R: Read>(
35 reader: &mut R,
36 ) -> Result<Self, borsh::io::Error> {
37 let value = u8::deserialize_reader(reader)?;
38 Ok(Self(value))
39 }
40}
41
42impl AccountMeta {
43 pub fn new(index: u8, is_signer: bool) -> Self {
44 Self::try_new(index, is_signer, true).expect("index is out of range")
45 }
46 pub fn new_readonly(index: u8, is_signer: bool) -> Self {
47 Self::try_new(index, is_signer, false).expect("index is out of range")
48 }
49
50 pub fn try_new(
51 index: u8,
52 is_signer: bool,
53 is_writable: bool,
54 ) -> Option<Self> {
55 if index >= MAX_PUBKEYS {
56 return None;
57 }
58 let mut packed = index;
59 if is_signer {
60 packed |= SIGNER_MASK;
61 }
62 if is_writable {
63 packed |= WRITABLE_MASK;
64 }
65 Some(Self(packed))
66 }
67
68 pub fn key(self) -> u8 {
69 self.0 & ACCOUNT_INDEX_MASK
70 }
71
72 pub fn is_signer(self) -> bool {
73 (self.0 & SIGNER_MASK) != 0
74 }
75
76 pub fn is_writable(self) -> bool {
77 (self.0 & WRITABLE_MASK) != 0
78 }
79
80 pub fn set_index(&mut self, new_index: u8) {
81 *self = Self::try_new(new_index, self.is_signer(), self.is_writable())
82 .expect("index is out of range");
83 }
84
85 pub fn to_byte(self) -> u8 {
86 self.0
87 }
88
89 pub fn from_byte(value: u8) -> Option<Self> {
90 Self::try_new(
91 value & ACCOUNT_INDEX_MASK,
92 (value & SIGNER_MASK) != 0,
93 (value & WRITABLE_MASK) != 0,
94 )
95 }
96}
97
98impl ClearText for AccountMeta {
99 type Output = MaybeEncryptedAccountMeta;
100
101 fn cleartext(self) -> Self::Output {
102 MaybeEncryptedAccountMeta::ClearText(self)
103 }
104}
105
106#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
107pub struct EncryptableAccountMeta {
108 pub account_meta: AccountMeta,
109 pub is_encryptable: bool,
110}