use crate::{BitsWrapper, Error, MutBits};
pub const fn array_concat_2(a: [u8; 2], b: [u8; 2]) -> [u8; 4] {
let [c, d] = b;
let [a, b] = a;
[a, b, c, d]
}
pub const fn array_split_2(a: [u8; 4]) -> ([u8; 2], [u8; 2]) {
let [a, b, c, d] = a;
([a, b], [c, d])
}
pub const fn array_concat_4(a: [u8; 4], b: [u8; 4]) -> [u8; 8] {
let [e, f, g, h] = b;
let [a, b, c, d] = a;
[a, b, c, d, e, f, g, h]
}
pub const fn array_split_4(a: [u8; 8]) -> ([u8; 4], [u8; 4]) {
let [a, b, c, d, e, f, g, h] = a;
([a, b, c, d], [e, f, g, h])
}
pub const fn array_concat_8(a: [u8; 8], b: [u8; 8]) -> [u8; 16] {
let [i, j, k, l, m, n, o, p] = b;
let [a, b, c, d, e, f, g, h] = a;
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]
}
pub const fn array_split_8(a: [u8; 16]) -> ([u8; 8], [u8; 8]) {
let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = a;
([a, b, c, d, e, f, g, h], [i, j, k, l, m, n, o, p])
}
pub const fn array_concat_16(a: [u8; 16], b: [u8; 16]) -> [u8; 32] {
let [q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af] = b;
let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = a;
[
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac,
ad, ae, af,
]
}
pub const fn array_split_16(a: [u8; 32]) -> ([u8; 16], [u8; 16]) {
let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af] =
a;
(
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p],
[q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af],
)
}
pub trait ToBEBytes<const N: usize> {
fn to_be_bytes(&self) -> [u8; N];
}
pub trait FromBEBytes<const N: usize> {
fn from_be_bytes(bytes: [u8; N]) -> Self;
}
impl ToBEBytes<1> for u8 {
fn to_be_bytes(&self) -> [u8; 1] {
[*self]
}
}
impl FromBEBytes<1> for u8 {
fn from_be_bytes(bytes: [u8; 1]) -> u8 {
bytes[0]
}
}
impl ToBEBytes<2> for u16 {
fn to_be_bytes(&self) -> [u8; 2] {
u16::to_be_bytes(*self)
}
}
impl FromBEBytes<2> for u16 {
fn from_be_bytes(bytes: [u8; 2]) -> u16 {
u16::from_be_bytes(bytes)
}
}
impl ToBEBytes<4> for u32 {
fn to_be_bytes(&self) -> [u8; 4] {
u32::to_be_bytes(*self)
}
}
impl<const N: usize, const Y: usize> ToBEBytes<Y> for [u32; N] {
fn to_be_bytes(&self) -> [u8; Y] {
let mut out = [0u8; Y];
let mut wr = BitsWrapper::Owned(out.as_mut_slice());
for v in self {
let _ = wr.write_be_u32(*v);
}
out
}
}
impl FromBEBytes<4> for u32 {
fn from_be_bytes(bytes: [u8; 4]) -> u32 {
u32::from_be_bytes(bytes)
}
}
impl FromBEBytes<8> for [u32; 2] {
fn from_be_bytes(bytes: [u8; 8]) -> [u32; 2] {
let (a, b) = array_split_4(bytes);
[u32::from_be_bytes(a), u32::from_be_bytes(b)]
}
}
impl FromBEBytes<16> for [u32; 4] {
fn from_be_bytes(bytes: [u8; 16]) -> [u32; 4] {
let (a, b) = array_split_8(bytes);
let (c, d) = array_split_4(b);
let (a, b) = array_split_4(a);
[
u32::from_be_bytes(a),
u32::from_be_bytes(b),
u32::from_be_bytes(c),
u32::from_be_bytes(d),
]
}
}
impl ToBEBytes<4> for f32 {
fn to_be_bytes(&self) -> [u8; 4] {
f32::to_be_bytes(*self)
}
}
impl FromBEBytes<4> for f32 {
fn from_be_bytes(bytes: [u8; 4]) -> f32 {
f32::from_be_bytes(bytes)
}
}
impl ToBEBytes<8> for [f32; 2] {
fn to_be_bytes(&self) -> [u8; 8] {
let [a, b] = *self;
array_concat_4(f32::to_be_bytes(a), f32::to_be_bytes(b))
}
}
impl FromBEBytes<8> for [f32; 2] {
fn from_be_bytes(bytes: [u8; 8]) -> [f32; 2] {
let (a, b) = array_split_4(bytes);
[f32::from_be_bytes(a), f32::from_be_bytes(b)]
}
}
impl ToBEBytes<8> for u64 {
fn to_be_bytes(&self) -> [u8; 8] {
u64::to_be_bytes(*self)
}
}
impl FromBEBytes<8> for u64 {
fn from_be_bytes(bytes: [u8; 8]) -> u64 {
u64::from_be_bytes(bytes)
}
}
impl ToBEBytes<8> for f64 {
fn to_be_bytes(&self) -> [u8; 8] {
f64::to_be_bytes(*self)
}
}
impl FromBEBytes<8> for f64 {
fn from_be_bytes(bytes: [u8; 8]) -> f64 {
f64::from_be_bytes(bytes)
}
}
impl ToBEBytes<16> for [f64; 2] {
fn to_be_bytes(&self) -> [u8; 16] {
let [a, b] = *self;
array_concat_8(a.to_be_bytes(), b.to_be_bytes())
}
}
impl FromBEBytes<16> for [f64; 2] {
fn from_be_bytes(bytes: [u8; 16]) -> [f64; 2] {
let (a, b) = array_split_8(bytes);
[f64::from_be_bytes(a), f64::from_be_bytes(b)]
}
}
impl ToBEBytes<16> for [u64; 2] {
fn to_be_bytes(&self) -> [u8; 16] {
let [a, b] = *self;
array_concat_8(u64::to_be_bytes(a), u64::to_be_bytes(b))
}
}
impl FromBEBytes<16> for [u64; 2] {
fn from_be_bytes(bytes: [u8; 16]) -> [u64; 2] {
let (a, b) = array_split_8(bytes);
[u64::from_be_bytes(a), u64::from_be_bytes(b)]
}
}
impl ToBEBytes<16> for u128 {
fn to_be_bytes(&self) -> [u8; 16] {
u128::to_be_bytes(*self)
}
}
impl FromBEBytes<16> for u128 {
fn from_be_bytes(bytes: [u8; 16]) -> u128 {
u128::from_be_bytes(bytes)
}
}
impl ToBEBytes<32> for [u128; 2] {
fn to_be_bytes(&self) -> [u8; 32] {
let [a, b] = *self;
array_concat_16(u128::to_be_bytes(a), u128::to_be_bytes(b))
}
}
impl FromBEBytes<32> for [u128; 2] {
fn from_be_bytes(bytes: [u8; 32]) -> [u128; 2] {
let (a, b) = array_split_16(bytes);
[u128::from_be_bytes(a), u128::from_be_bytes(b)]
}
}
pub trait WriteToBEBits {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error>;
}
impl WriteToBEBits for u8 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_u8(*self)
}
}
impl WriteToBEBits for u16 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_u16(*self)
}
}
impl WriteToBEBits for u32 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_u32(*self)
}
}
impl WriteToBEBits for u64 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_u64(*self)
}
}
impl WriteToBEBits for u128 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_u128(*self)
}
}
impl WriteToBEBits for f32 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_f32(*self)
}
}
impl WriteToBEBits for f64 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_f64(*self)
}
}
impl WriteToBEBits for i8 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_i8(*self)
}
}
impl WriteToBEBits for i16 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_i16(*self)
}
}
impl WriteToBEBits for i32 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_i32(*self)
}
}
impl WriteToBEBits for i64 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_i64(*self)
}
}
impl WriteToBEBits for i128 {
fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<(), Error> {
bits.write_be_i128(*self)
}
}
pub const fn u64_to_u128(val: [u64; 2]) -> u128 {
let [a, b] = val;
u128::from_be_bytes(array_concat_8(u64::to_be_bytes(a), u64::to_be_bytes(b)))
}
pub const fn u32_to_u64(val: [u32; 2]) -> u64 {
let [a, b] = val;
u64::from_be_bytes(array_concat_4(u32::to_be_bytes(a), u32::to_be_bytes(b)))
}
pub const fn u32_to_u128(val: [u32; 4]) -> u128 {
let [a, b, c, d] = val;
u64_to_u128([u32_to_u64([a, b]), u32_to_u64([c, d])])
}
pub const fn u16_to_u32(val: [u16; 2]) -> u32 {
let [a, b] = val;
u32::from_be_bytes(array_concat_2(u16::to_be_bytes(a), u16::to_be_bytes(b)))
}
pub const fn u16_to_u64(val: [u16; 4]) -> u64 {
let [a, b, c, d] = val;
u32_to_u64([u16_to_u32([a, b]), u16_to_u32([c, d])])
}
pub const fn u16_to_u128(val: [u16; 8]) -> u128 {
let [a, b, c, d, e, f, g, h] = val;
u64_to_u128([u16_to_u64([a, b, c, d]), u16_to_u64([e, f, g, h])])
}
pub const fn u128_to_u64(val: u128) -> [u64; 2] {
let a = val as u64;
let b = (val >> 64) as u64;
[b, a]
}
pub const fn u64_to_u32(val: u64) -> [u32; 2] {
let a = val as u32;
let b = (val >> 32) as u32;
[b, a]
}
pub const fn u32_to_u16(val: u32) -> [u16; 2] {
let a = val as u16;
let b = (val >> 16) as u16;
[b, a]
}
pub const fn u128_to_u32(val: u128) -> [u32; 4] {
let [a, b] = u128_to_u64(val);
let [c, d] = u64_to_u32(a);
let [e, f] = u64_to_u32(b);
[c, d, e, f]
}
pub const fn u64_to_u16(val: u64) -> [u16; 4] {
let [a, b] = u64_to_u32(val);
let [c, d] = u32_to_u16(a);
let [e, f] = u32_to_u16(b);
[c, d, e, f]
}
pub const fn u128_to_u16(val: u128) -> [u16; 8] {
let [a, b, c, d] = u128_to_u32(val);
let [e, f] = u32_to_u16(a);
let [g, h] = u32_to_u16(b);
let [i, j] = u32_to_u16(c);
let [k, l] = u32_to_u16(d);
[e, f, g, h, i, j, k, l]
}