use solana_program::pubkey::Pubkey;
use crate::utils::split_at_checked;
pub(crate) trait DeserializeRef<'a>: Sized {
fn deserialize_ref(slice: &mut &'a [u8]) -> Option<Self>;
}
pub struct MessageDataRef<'a> {
pub msg_hash: &'a [u8; 32],
pub total_fee: u128,
pub selector: &'a [u8; 32],
pub sender_addr: &'a [u8],
pub dest_addr: Pubkey,
pub payload: &'a [u8],
pub reserved: &'a [u8],
pub transmitter_params: &'a [u8],
pub src_chain_id: u128,
pub src_block_number: u128,
pub src_op_tx_id: &'a [[u8; 32]; 2],
}
impl<'a> DeserializeRef<'a> for MessageDataRef<'a> {
fn deserialize_ref(data: &mut &'a [u8]) -> Option<Self> {
let mut read_data = |count| {
let (left, right) = split_at_checked(data, count)?;
*data = right;
Some(left)
};
let msg_hash = read_data(32)?.try_into().unwrap();
let total_fee = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
let selector = read_data(32)?.try_into().unwrap();
let sender_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
let sender_addr = read_data(sender_len)?;
let dest_addr = Pubkey::new_from_array(read_data(32)?.try_into().unwrap());
let payload_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
let payload = read_data(payload_len)?;
let reserved_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
let reserved = read_data(reserved_len)?;
let transmitter_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
let transmitter_params = read_data(transmitter_len)?;
let src_chain_id = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
let src_block_number = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
let src_op_tx_id: &[u8; 64] = read_data(64)?.try_into().unwrap();
let src_op_tx_id: &[[u8; 32]; 2] = bytemuck::cast_ref(src_op_tx_id);
Some(MessageDataRef {
payload,
src_chain_id,
sender_addr,
msg_hash,
total_fee,
selector,
dest_addr,
reserved,
transmitter_params,
src_block_number,
src_op_tx_id,
})
}
}