Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

KiB

Copyright (C) 2016-2017, 2019-2020, 2022, 2024-2025  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2016-2017".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

//! # Bytes

use {
    core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize},
    self::inner::Inner,
};

mod inner;

/// # Bytes
///
/// This struct is just a simple container for some primitive numbers. It is used in [`fmt()`][fn:fmt], [`fmt_as_parts()`][fn:fmt_as_parts]...
///
/// [fn:fmt]: fn.fmt.html
/// [fn:fmt_as_parts]: fn.fmt_as_parts.html
#[derive(Debug)]
pub struct Bytes {
    inner: Inner,
}

impl Bytes {

    /// # Casts to `f64`
    pub (crate) const fn as_f64_lossy(&self) -> f64 {
        match self.inner {
            Inner::USize(n) => n as f64,
            Inner::U64(n) => n as f64,
            Inner::U128(n) => n as f64,
            Inner::F64(f) => f,
        }
    }

    /// # Casts to `u64`
    pub (crate) fn as_u64(&self) -> Option<u64> {
        match self.inner {
            Inner::USize(n) => n.try_into().ok(),
            Inner::U64(n) => Some(n),
            Inner::U128(n) => n.try_into().ok(),
            Inner::F64(_) => None,
        }
    }

}

impl From<usize> for Bytes {

    fn from(n: usize) -> Self {
        Self {
            inner: Inner::USize(n),
        }
    }

}

impl From<u128> for Bytes {

    fn from(n: u128) -> Self {
        Self {
            inner: Inner::U128(n),
        }
    }

}

impl From<f64> for Bytes {

    fn from(f: f64) -> Self {
        Self {
            inner: Inner::F64(f),
        }
    }

}

impl From<f32> for Bytes {

    fn from(f: f32) -> Self {
        Self {
            inner: Inner::F64(f64::from(f)),
        }
    }

}

macro_rules! impl_from_ux_for_bytes { ($($ty: ty),+$(,)?) => {
    $(
        impl From<$ty> for Bytes {

            fn from(n: $ty) -> Self {
                Self {
                    inner: Inner::U64(n.into()),
                }
            }

        }
    )+
}}

impl_from_ux_for_bytes!(u8, u16, u32, u64);

macro_rules! impl_from_non_zero_ux_for_bytes { ($($ty: ty),+$(,)?) => {
    $(
        impl From<$ty> for Bytes {

            fn from(n: $ty) -> Self {
                Self::from(n.get())
            }

        }
    )+
}}

impl_from_non_zero_ux_for_bytes!(NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize);