solana_primitives/builder/
data.rs1use crate::types::Pubkey;
4
5pub struct InstructionDataBuilder {
7 data: Vec<u8>,
8}
9
10impl InstructionDataBuilder {
11 pub fn new() -> Self {
13 Self { data: Vec::new() }
14 }
15
16 pub fn instruction(mut self, discriminant: u8) -> Self {
18 self.data.push(discriminant);
19 self
20 }
21
22 pub fn bytes(mut self, bytes: &[u8]) -> Self {
24 self.data.extend_from_slice(bytes);
25 self
26 }
27
28 pub fn u8(mut self, value: u8) -> Self {
30 self.data.push(value);
31 self
32 }
33
34 pub fn u16(mut self, value: u16) -> Self {
36 self.data.extend_from_slice(&value.to_le_bytes());
37 self
38 }
39
40 pub fn u32(mut self, value: u32) -> Self {
42 self.data.extend_from_slice(&value.to_le_bytes());
43 self
44 }
45
46 pub fn u64(mut self, value: u64) -> Self {
48 self.data.extend_from_slice(&value.to_le_bytes());
49 self
50 }
51
52 pub fn u128(mut self, value: u128) -> Self {
54 self.data.extend_from_slice(&value.to_le_bytes());
55 self
56 }
57
58 pub fn i8(mut self, value: i8) -> Self {
60 self.data.push(value as u8);
61 self
62 }
63
64 pub fn i16(mut self, value: i16) -> Self {
66 self.data.extend_from_slice(&value.to_le_bytes());
67 self
68 }
69
70 pub fn i32(mut self, value: i32) -> Self {
72 self.data.extend_from_slice(&value.to_le_bytes());
73 self
74 }
75
76 pub fn i64(mut self, value: i64) -> Self {
78 self.data.extend_from_slice(&value.to_le_bytes());
79 self
80 }
81
82 pub fn i128(mut self, value: i128) -> Self {
84 self.data.extend_from_slice(&value.to_le_bytes());
85 self
86 }
87
88 pub fn bool(mut self, value: bool) -> Self {
90 self.data.push(value as u8);
91 self
92 }
93
94 pub fn pubkey(mut self, pubkey: &Pubkey) -> Self {
96 self.data.extend_from_slice(pubkey.as_bytes());
97 self
98 }
99
100 pub fn option_pubkey(mut self, pubkey: Option<&Pubkey>) -> Self {
102 match pubkey {
103 Some(pk) => {
104 self.data.push(1);
105 self.data.extend_from_slice(pk.as_bytes());
106 }
107 None => {
108 self.data.push(0);
109 }
110 }
111 self
112 }
113
114 pub fn string(mut self, s: &str) -> Self {
116 let bytes = s.as_bytes();
117 self.data
118 .extend_from_slice(&(bytes.len() as u32).to_le_bytes());
119 self.data.extend_from_slice(bytes);
120 self
121 }
122
123 pub fn build(self) -> Vec<u8> {
125 self.data
126 }
127}
128
129impl Default for InstructionDataBuilder {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use crate::types::Pubkey;
139
140 #[test]
141 fn test_instruction_data_builder() {
142 let data = InstructionDataBuilder::new()
143 .instruction(3)
144 .u64(1000000)
145 .u8(6)
146 .bool(true)
147 .build();
148
149 let expected = vec![
150 3, 0x40, 0x42, 0x0F, 0, 0, 0, 0, 0, 6, 1, ];
155
156 assert_eq!(data, expected);
157 }
158
159 #[test]
160 fn test_instruction_data_builder_with_pubkey() {
161 let pubkey = Pubkey::new([1u8; 32]);
162
163 let data = InstructionDataBuilder::new()
164 .instruction(0)
165 .pubkey(&pubkey)
166 .build();
167
168 let mut expected = vec![0];
169 expected.extend_from_slice(&[1u8; 32]);
170
171 assert_eq!(data, expected);
172 }
173
174 #[test]
175 fn test_instruction_data_builder_with_option() {
176 let pubkey = Pubkey::new([2u8; 32]);
177
178 let data = InstructionDataBuilder::new()
180 .instruction(1)
181 .option_pubkey(Some(&pubkey))
182 .build();
183
184 let mut expected = vec![1, 1]; expected.extend_from_slice(&[2u8; 32]);
186 assert_eq!(data, expected);
187
188 let data_none = InstructionDataBuilder::new()
190 .instruction(1)
191 .option_pubkey(None)
192 .build();
193
194 assert_eq!(data_none, vec![1, 0]); }
196
197 #[test]
198 fn test_instruction_data_builder_with_string() {
199 let data = InstructionDataBuilder::new()
200 .instruction(5)
201 .string("hello")
202 .build();
203
204 let expected = vec![
205 5, 5, 0, 0, 0, b'h', b'e', b'l', b'l', b'o', ];
209
210 assert_eq!(data, expected);
211 }
212}