use std::marker::PhantomData;

use bytemuck::{Pod, Zeroable};

#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(transparent)]
pub struct BigEndian<T>([u8; size_of::<T>()], PhantomData<T>)
where
    [u8; size_of::<T>()]: Sized + Zeroable + Pod;

#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct App0Header {
    pub length: BigEndian<u16>,
    pub identifier: [u8; 5],
    pub version: BigEndian<u16>,
    pub units: u8,
    pub xdensity: BigEndian<u16>,
    pub ydensity: BigEndian<u16>,
    pub xthumbnail: u8,
    pub ythumbnail: u8,
}

macro_rules! impl_big_endian {
    ($($ty:ty),+) => {
        $(
            impl BigEndian<$ty> {
                pub fn read(&self) -> $ty {
                    <$ty>::from_be_bytes(self.0)
                }
            }
        )+
    };
}

impl_big_endian!(u16, u32);
