1use std::borrow::Cow;
2
3use super::{features::FeaturesSet, status::ErStatus, version::v0::RecordV0};
4use borsh::{BorshDeserialize, BorshSerialize};
5use solana_program::pubkey::Pubkey;
6
7use crate::{consts::ER_RECORD_SEED, ID};
8
9#[derive(Debug, BorshSerialize, BorshDeserialize)]
10#[cfg_attr(not(feature = "entrypoint"), derive(PartialEq, Eq, Clone))]
11pub enum ErRecord {
12 V0(RecordV0),
13}
14
15impl ErRecord {
16 pub fn pda(&self) -> (Pubkey, u8) {
18 Pubkey::find_program_address(&self.seeds(), &ID)
19 }
20
21 pub fn seeds(&self) -> [&[u8]; 2] {
23 [ER_RECORD_SEED, self.identity().as_ref()]
24 }
25
26 pub fn identity(&self) -> &Pubkey {
28 match self {
29 Self::V0(r) => &r.identity,
30 }
31 }
32
33 pub fn addr(&self) -> &str {
35 match self {
36 Self::V0(v) => &v.addr,
37 }
38 }
39
40 pub fn base_fee(&self) -> u16 {
42 match self {
43 Self::V0(v) => v.base_fee,
44 }
45 }
46
47 pub fn features(&self) -> &FeaturesSet {
49 match self {
50 Self::V0(v) => &v.features,
51 }
52 }
53
54 pub fn block_time_ms(&self) -> u16 {
56 match self {
57 Self::V0(v) => v.block_time_ms,
58 }
59 }
60
61 pub fn status(&self) -> ErStatus {
63 match self {
64 Self::V0(v) => v.status,
65 }
66 }
67
68 pub fn load_average(&self) -> u32 {
70 match self {
71 Self::V0(v) => v.load_average,
72 }
73 }
74
75 pub fn country_code(&self) -> CountryCode {
77 match self {
78 Self::V0(v) => v.country_code,
79 }
80 }
81
82 pub fn set_addr(&mut self, addr: String) {
84 match self {
85 Self::V0(v) => v.addr = addr,
86 }
87 }
88
89 pub fn set_base_fee(&mut self, base_fee: u16) {
91 match self {
92 Self::V0(v) => v.base_fee = base_fee,
93 }
94 }
95
96 pub fn set_features(&mut self, features: FeaturesSet) {
98 match self {
99 Self::V0(v) => v.features = features,
100 }
101 }
102
103 pub fn set_block_time_ms(&mut self, block_time_ms: u16) {
105 match self {
106 Self::V0(v) => v.block_time_ms = block_time_ms,
107 }
108 }
109
110 pub fn set_status(&mut self, status: ErStatus) {
112 match self {
113 Self::V0(v) => v.status = status,
114 }
115 }
116
117 pub fn set_load_average(&mut self, load_average: u32) {
119 match self {
120 Self::V0(v) => v.load_average = load_average,
121 }
122 }
123
124 pub fn set_country_code(&mut self, country_code: CountryCode) {
126 match self {
127 Self::V0(v) => v.country_code = country_code,
128 }
129 }
130}
131
132#[derive(BorshDeserialize, BorshSerialize, Debug, Clone, Copy, PartialEq, Eq)]
133pub struct CountryCode([u8; 3]);
134
135impl<S: AsRef<[u8]>> From<S> for CountryCode {
136 fn from(value: S) -> Self {
137 const LEN: usize = std::mem::size_of::<CountryCode>();
138 let mut buf = [0u8; LEN];
139 buf.copy_from_slice(&value.as_ref()[..LEN]);
140 Self(buf)
141 }
142}
143
144impl CountryCode {
145 pub fn as_str(&self) -> Cow<'_, str> {
146 String::from_utf8_lossy(&self.0)
147 }
148}