triple_buf_64 0.1.1

A cheap lock-free triple buffer data structure that stores 64 bits of data
Documentation
/// A 64 bit data type that is used in realtime-safe lock-free triple
/// buffer.
///
/// Implementations for the following primitives are provided:
/// * [`u64`]
/// * [`i64`]
/// * [`f64`]
/// * [[`u32`]; 2]
/// * [[`i32`]; 2]
/// * [[`f32`]; 2]
/// * [[`u16`]; 4]
/// * [[`i16`]; 4]
/// * [[`u8`]; 8]
/// * [[`i8`]; 8]
/// * [[`bool`]; 8]
pub trait Data64Bit: Clone + Copy + Send {
    fn from_ne_bytes(bytes: [u8; 8]) -> Self;
    fn to_ne_bytes(self) -> [u8; 8];
}

macro_rules! data_x1 {
    ($ty:path) => {
        impl Data64Bit for $ty {
            fn from_ne_bytes(b: [u8; 8]) -> Self {
                <$ty>::from_ne_bytes(b)
            }
            fn to_ne_bytes(self) -> [u8; 8] {
                <$ty>::to_ne_bytes(self)
            }
        }
    };
}

macro_rules! data_x2 {
    ($ty:path) => {
        impl Data64Bit for [$ty; 2] {
            fn from_ne_bytes(b: [u8; 8]) -> Self {
                [
                    <$ty>::from_ne_bytes([b[0], b[1], b[2], b[3]]),
                    <$ty>::from_ne_bytes([b[4], b[5], b[6], b[7]]),
                ]
            }
            fn to_ne_bytes(self) -> [u8; 8] {
                let b0 = <$ty>::to_ne_bytes(self[0]);
                let b1 = <$ty>::to_ne_bytes(self[1]);
                [b0[0], b0[1], b0[2], b0[3], b1[0], b1[1], b1[2], b1[3]]
            }
        }
    };
}

macro_rules! data_x4 {
    ($ty:path) => {
        impl Data64Bit for [$ty; 4] {
            fn from_ne_bytes(b: [u8; 8]) -> Self {
                [
                    <$ty>::from_ne_bytes([b[0], b[1]]),
                    <$ty>::from_ne_bytes([b[2], b[3]]),
                    <$ty>::from_ne_bytes([b[4], b[5]]),
                    <$ty>::from_ne_bytes([b[6], b[7]]),
                ]
            }
            fn to_ne_bytes(self) -> [u8; 8] {
                let b0 = <$ty>::to_ne_bytes(self[0]);
                let b1 = <$ty>::to_ne_bytes(self[1]);
                let b2 = <$ty>::to_ne_bytes(self[2]);
                let b3 = <$ty>::to_ne_bytes(self[3]);
                [b0[0], b0[1], b1[0], b1[1], b2[0], b2[1], b3[0], b3[1]]
            }
        }
    };
}

data_x1!(u64);
data_x1!(i64);
data_x1!(f64);

data_x2!(u32);
data_x2!(i32);
data_x2!(f32);

data_x4!(u16);
data_x4!(i16);

impl Data64Bit for [u8; 8] {
    fn from_ne_bytes(bytes: [u8; 8]) -> Self {
        bytes
    }
    fn to_ne_bytes(self) -> [u8; 8] {
        self
    }
}

impl Data64Bit for [i8; 8] {
    fn from_ne_bytes(b: [u8; 8]) -> Self {
        [
            b[0].cast_signed(),
            b[1].cast_signed(),
            b[2].cast_signed(),
            b[3].cast_signed(),
            b[4].cast_signed(),
            b[5].cast_signed(),
            b[6].cast_signed(),
            b[7].cast_signed(),
        ]
    }
    fn to_ne_bytes(self) -> [u8; 8] {
        [
            self[0].cast_unsigned(),
            self[1].cast_unsigned(),
            self[2].cast_unsigned(),
            self[3].cast_unsigned(),
            self[4].cast_unsigned(),
            self[5].cast_unsigned(),
            self[6].cast_unsigned(),
            self[7].cast_unsigned(),
        ]
    }
}

impl Data64Bit for [bool; 8] {
    fn from_ne_bytes(b: [u8; 8]) -> Self {
        [
            b[0] != 0,
            b[1] != 0,
            b[2] != 0,
            b[3] != 0,
            b[4] != 0,
            b[5] != 0,
            b[6] != 0,
            b[7] != 0,
        ]
    }
    fn to_ne_bytes(self) -> [u8; 8] {
        [
            self[0] as u8,
            self[1] as u8,
            self[2] as u8,
            self[3] as u8,
            self[4] as u8,
            self[5] as u8,
            self[6] as u8,
            self[7] as u8,
        ]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn data_u64() {
        let val = 4984519452405141540u64;
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, Data64Bit::from_ne_bytes(bytes));
    }

    #[test]
    fn data_i64() {
        let val = -984519452405141540i64;
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, Data64Bit::from_ne_bytes(bytes));
    }

    #[test]
    fn data_f64() {
        let val = -98.4519452405141540f64;
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, Data64Bit::from_ne_bytes(bytes));
    }

    #[test]
    fn data_u32() {
        let val: [u32; 2] = [1755451428u32, 582094884u32];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[u32; 2] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_i32() {
        let val: [i32; 2] = [-755451428i32, 582094884i32];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[i32; 2] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_f32() {
        let val: [f32; 2] = [-7554.51428f32, 5.82094884f32];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[f32; 2] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_u16() {
        let val: [u16; 4] = [21029u16, 38445u16, 8u16, 5165u16];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[u16; 4] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_i16() {
        let val: [i16; 4] = [21029i16, -28445i16, -8i16, 5165i16];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[i16; 4] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_u8() {
        let val: [u8; 8] = [253u8, 12u8, 50u8, 3u8, 128u8, 130u8, 69u8, 67u8];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[u8; 8] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_i8() {
        let val: [i8; 8] = [-120i8, 12i8, 50i8, -3i8, 127i8, 23i8, 69i8, 67i8];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[i8; 8] as Data64Bit>::from_ne_bytes(bytes));
    }

    #[test]
    fn data_bool() {
        let val: [bool; 8] = [true, true, false, true, false, false, true, false];
        let bytes = Data64Bit::to_ne_bytes(val);
        assert_eq!(val, <[bool; 8] as Data64Bit>::from_ne_bytes(bytes));
    }
}