use anchor_lang::prelude::{*, borsh::BorshSchema};
use crate::errors::ReflectErrorCodes;
use std::io::Write;
pub const RECIPIENTS_LIMIT: usize = 10;
#[repr(C)]
#[derive(BorshSchema, Default, AnchorSerialize, AnchorDeserialize, Debug, PartialEq, Eq, InitSpace, Clone, Copy)]
pub struct Recipient {
pub address: Pubkey,
pub cut: u16,
}
impl Recipient {
pub fn deserialize(buf: &mut &[u8]) -> Result<Self> {
let address = Pubkey::deserialize(buf)?;
let cut = u16::deserialize(buf)?;
Ok(Recipient { address, cut })
}
pub fn try_serialise<W: Write>(&self, writer: &mut W) -> Result<()> {
self.address.serialize(writer)?;
self.cut.serialize(writer)?;
Ok(())
}
}
#[repr(C)]
#[derive(BorshSchema, AnchorDeserialize, AnchorSerialize, Default, Debug, PartialEq, Eq, Clone, InitSpace, Copy)]
pub struct Recipients {
pub recipients: [Recipient; RECIPIENTS_LIMIT],
pub recipients_count: u8,
}
impl Recipients {
pub fn deserialize(buf: &mut &[u8]) -> Result<Self> {
let mut recipients = [Recipient::default(); RECIPIENTS_LIMIT];
for i in 0..RECIPIENTS_LIMIT {
recipients[i] = Recipient::deserialize(buf)?;
}
let recipients_count = u8::deserialize(buf)?;
Ok(Recipients {
recipients,
recipients_count,
})
}
pub fn try_serialise<W: Write>(&self, writer: &mut W) -> Result<()> {
for recipient in &self.recipients {
recipient.try_serialise(writer)?;
}
self.recipients_count.serialize(writer)?;
Ok(())
}
pub fn get_recipients_vec(&self) -> Vec<Recipient> {
self.recipients[..self.recipients_count as usize]
.iter()
.copied()
.collect()
}
pub fn get_cuts(&self) -> Vec<u16> {
self.recipients[..self.recipients_count as usize]
.iter()
.map(|recipient| recipient.cut)
.collect()
}
pub fn set_recipients(&mut self, recipients: &Vec<Recipient>) {
self.recipients
.iter_mut()
.zip(recipients.iter())
.for_each(|(dest, src)| *dest = *src);
self.recipients[recipients.len()..].fill(Recipient::default());
self.recipients_count = recipients.len() as u8;
}
pub fn recipients_count(&self) -> usize {
self.recipients_count as usize
}
}
pub const RECIPIENTS_START: usize = 0;
pub const USDC_CONTROLLER_SIZE: usize = 10_000;
pub fn deserialise_recipients(data_usdc_controller: &[u8]) -> Result<Recipients> {
if data_usdc_controller.len() < RECIPIENTS_START + 40 {
return Err(ReflectErrorCodes::InsufficientData.into());
}
let mut slice = &data_usdc_controller[RECIPIENTS_START..];
Recipients::deserialize(&mut slice)
.map_err(|_| ReflectErrorCodes::DeserializationError.into())
}