mod boolean;
mod field_ref;
mod integers;
mod typed_address;
pub use boolean::WireBool;
pub use field_ref::{FieldMut, FieldRef};
pub use integers::{WireI128, WireI16, WireI32, WireI64, WireU128, WireU16, WireU32, WireU64};
pub use typed_address::{
Authority, Mint, Program, Token, TokenAccount, TypedAddress, UntypedAddress,
};
pub unsafe trait WireType: Copy + Sized {
const WIRE_SIZE: usize;
const CANONICAL_NAME: &'static str;
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct LayoutFingerprint {
bytes: [u8; 8],
}
impl LayoutFingerprint {
#[inline(always)]
pub const fn from_bytes(bytes: [u8; 8]) -> Self {
Self { bytes }
}
#[inline(always)]
pub const fn as_bytes(&self) -> &[u8; 8] {
&self.bytes
}
#[inline(always)]
pub const fn matches(&self, other: &LayoutFingerprint) -> bool {
let a = &self.bytes;
let b = &other.bytes;
a[0] == b[0]
&& a[1] == b[1]
&& a[2] == b[2]
&& a[3] == b[3]
&& a[4] == b[4]
&& a[5] == b[5]
&& a[6] == b[6]
&& a[7] == b[7]
}
#[inline(always)]
pub const fn differs_from(&self, other: &LayoutFingerprint) -> bool {
!self.matches(other)
}
#[inline]
pub fn verify_header(&self, data: &[u8]) -> Result<(), hopper_runtime::error::ProgramError> {
if data.len() < 12 {
return Err(hopper_runtime::error::ProgramError::AccountDataTooSmall);
}
let mut id = [0u8; 8];
id.copy_from_slice(&data[4..12]);
if id != self.bytes {
return Err(hopper_runtime::error::ProgramError::InvalidAccountData);
}
Ok(())
}
}
pub struct FingerprintTransition {
pub from: LayoutFingerprint,
pub to: LayoutFingerprint,
}
impl FingerprintTransition {
#[inline(always)]
pub const fn new(from: LayoutFingerprint, to: LayoutFingerprint) -> Self {
Self { from, to }
}
#[inline(always)]
pub const fn assert_valid(&self) {
assert!(
self.from.differs_from(&self.to),
"Layout fingerprints must differ between versions"
);
}
}