use rust_decimal::prelude::*;
use faster_hex::hex_string;
use crate::prelude::*;
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct PackedQuoteHeader {
pub signed_slothash: [u8; 32],
}
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct PackedFeedInfo {
feed_id: [u8; 32],
feed_value: i128,
min_oracle_samples: u8,
}
impl PackedFeedInfo {
pub const PACKED_SIZE: usize = 49;
#[inline(always)]
pub fn feed_id(&self) -> &[u8; 32] {
&self.feed_id
}
#[inline(always)]
pub fn hex_id(&self) -> String {
String::from("0x") + &hex_string(self.feed_id())
}
#[inline(always)]
pub fn feed_value(&self) -> i128 {
self.feed_value
}
#[inline(always)]
pub fn value(&self) -> Decimal {
Decimal::from_i128_with_scale(self.feed_value(), PRECISION).normalize()
}
#[inline(always)]
pub fn min_oracle_samples(&self) -> u8 {
self.min_oracle_samples
}
}
#[cfg(test)]
mod tests {
use super::*;
use rust_decimal::Decimal;
#[test]
fn test_packed_feed_info_layout() {
let mut data = [0u8; 49];
data[0..32].fill(0x42);
let feed_value_scaled: i128 = 115525650000000000000000i128;
let value_bytes = feed_value_scaled.to_le_bytes();
data[32..48].copy_from_slice(&value_bytes);
data[48] = 5;
let feed_info = unsafe { &*(data.as_ptr() as *const PackedFeedInfo) };
let raw_value = feed_info.feed_value();
println!("Raw feed value: {}", raw_value);
println!("Expected: {}", feed_value_scaled);
assert_eq!(raw_value, feed_value_scaled);
let decimal_value = feed_info.value();
println!("Decimal value: {}", decimal_value);
assert_eq!(feed_info.min_oracle_samples(), 5);
assert_eq!(feed_info.feed_id()[0], 0x42);
println!("✅ Test passed! Feed value reads correctly: {}", decimal_value);
}
}