use crate::types::Pubkey;
pub struct InstructionDataBuilder {
data: Vec<u8>,
}
impl InstructionDataBuilder {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn instruction(mut self, discriminant: u8) -> Self {
self.data.push(discriminant);
self
}
pub fn bytes(mut self, bytes: &[u8]) -> Self {
self.data.extend_from_slice(bytes);
self
}
pub fn u8(mut self, value: u8) -> Self {
self.data.push(value);
self
}
pub fn u16(mut self, value: u16) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn u32(mut self, value: u32) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn u64(mut self, value: u64) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn u128(mut self, value: u128) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn i8(mut self, value: i8) -> Self {
self.data.push(value as u8);
self
}
pub fn i16(mut self, value: i16) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn i32(mut self, value: i32) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn i64(mut self, value: i64) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn i128(mut self, value: i128) -> Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn bool(mut self, value: bool) -> Self {
self.data.push(value as u8);
self
}
pub fn pubkey(mut self, pubkey: &Pubkey) -> Self {
self.data.extend_from_slice(pubkey.as_bytes());
self
}
pub fn option_pubkey(mut self, pubkey: Option<&Pubkey>) -> Self {
match pubkey {
Some(pk) => {
self.data.push(1);
self.data.extend_from_slice(pk.as_bytes());
}
None => {
self.data.push(0);
}
}
self
}
pub fn string(mut self, s: &str) -> Self {
let bytes = s.as_bytes();
self.data
.extend_from_slice(&(bytes.len() as u32).to_le_bytes());
self.data.extend_from_slice(bytes);
self
}
pub fn build(self) -> Vec<u8> {
self.data
}
}
impl Default for InstructionDataBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::Pubkey;
#[test]
fn test_instruction_data_builder() {
let data = InstructionDataBuilder::new()
.instruction(3)
.u64(1000000)
.u8(6)
.bool(true)
.build();
let expected = vec![
3, 0x40, 0x42, 0x0F, 0, 0, 0, 0, 0, 6, 1, ];
assert_eq!(data, expected);
}
#[test]
fn test_instruction_data_builder_with_pubkey() {
let pubkey = Pubkey::new([1u8; 32]);
let data = InstructionDataBuilder::new()
.instruction(0)
.pubkey(&pubkey)
.build();
let mut expected = vec![0];
expected.extend_from_slice(&[1u8; 32]);
assert_eq!(data, expected);
}
#[test]
fn test_instruction_data_builder_with_option() {
let pubkey = Pubkey::new([2u8; 32]);
let data = InstructionDataBuilder::new()
.instruction(1)
.option_pubkey(Some(&pubkey))
.build();
let mut expected = vec![1, 1]; expected.extend_from_slice(&[2u8; 32]);
assert_eq!(data, expected);
let data_none = InstructionDataBuilder::new()
.instruction(1)
.option_pubkey(None)
.build();
assert_eq!(data_none, vec![1, 0]); }
#[test]
fn test_instruction_data_builder_with_string() {
let data = InstructionDataBuilder::new()
.instruction(5)
.string("hello")
.build();
let expected = vec![
5, 5, 0, 0, 0, b'h', b'e', b'l', b'l', b'o', ];
assert_eq!(data, expected);
}
}