use { crate::{ message::{AccumulatorSerializer, MessageSchema}, state::PriceAccount, }, anchor_lang::prelude::*, std::io::Write, }; #[repr(C)] #[derive(Clone, Default, Debug, Eq, PartialEq)] pub struct MessageHeader { pub schema: u8, pub version: u16, pub size: u32, } impl MessageHeader { pub const CURRENT_VERSION: u8 = 2; pub fn new(schema: MessageSchema, size: u32) -> Self { Self { schema: schema.to_u8(), version: Self::CURRENT_VERSION as u16, size, } } } #[repr(C)] #[derive(Clone, Default, Debug, Eq, PartialEq)] pub struct CompactPriceMessage { pub header: MessageHeader, pub id: u64, pub price: u64, pub price_expo: u64, } impl CompactPriceMessage { // size without header pub const SIZE: usize = 24; } impl AccumulatorSerializer for CompactPriceMessage { fn accumulator_serialize(&self) -> Result> { let mut bytes = vec![]; bytes.write_all(&self.header.schema.to_be_bytes())?; bytes.write_all(&self.header.version.to_be_bytes())?; bytes.write_all(&self.header.size.to_be_bytes())?; bytes.write_all(&self.id.to_be_bytes())?; bytes.write_all(&self.price.to_be_bytes())?; bytes.write_all(&self.price_expo.to_be_bytes())?; Ok(bytes) } } impl From<&PriceAccount> for CompactPriceMessage { fn from(other: &PriceAccount) -> Self { Self { header: MessageHeader::new(MessageSchema::Compact, Self::SIZE as u32), id: other.id, price: other.price, price_expo: other.price_expo, } } } #[repr(C)] #[derive(Clone, Default, Debug, Eq, PartialEq)] pub struct FullPriceMessage { pub header: MessageHeader, pub id: u64, pub price: u64, pub price_expo: u64, pub ema: u64, pub ema_expo: u64, } impl FullPriceMessage { pub const SIZE: usize = 40; } impl From<&PriceAccount> for FullPriceMessage { fn from(other: &PriceAccount) -> Self { Self { header: MessageHeader::new(MessageSchema::Full, Self::SIZE as u32), id: other.id, price: other.price, price_expo: other.price_expo, ema: other.ema, ema_expo: other.ema_expo, } } } impl AccumulatorSerializer for FullPriceMessage { fn accumulator_serialize(&self) -> Result> { let mut bytes = vec![]; bytes.write_all(&self.header.schema.to_be_bytes())?; bytes.write_all(&self.header.version.to_be_bytes())?; bytes.write_all(&self.header.size.to_be_bytes())?; bytes.write_all(&self.id.to_be_bytes())?; bytes.write_all(&self.price.to_be_bytes())?; bytes.write_all(&self.price_expo.to_be_bytes())?; bytes.write_all(&self.ema.to_be_bytes())?; bytes.write_all(&self.ema_expo.to_be_bytes())?; Ok(bytes) } } #[repr(C)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct DummyPriceMessage { pub header: MessageHeader, pub data: Vec, } impl DummyPriceMessage { pub const SIZE: usize = 1017; pub fn new(msg_size: u16) -> Self { Self { header: MessageHeader::new(MessageSchema::Dummy, msg_size as u32), data: vec![0u8; msg_size as usize], } } } impl AccumulatorSerializer for DummyPriceMessage { fn accumulator_serialize(&self) -> Result> { let mut bytes = vec![]; bytes.write_all(&self.header.schema.to_be_bytes())?; bytes.write_all(&self.header.version.to_be_bytes())?; bytes.write_all(&self.header.size.to_be_bytes())?; bytes.extend_from_slice(&self.data); Ok(bytes) } }