1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#![no_std]

mod bool_;
mod float;
mod impl_;
mod int;
#[cfg(test)]
mod tests;

use flatty_base::traits::Flat;

/// Type that can be safely transfered between different machines.
///
/// # Safety
///
/// Implementing this trait must guarantee that `Self` has the same binary representation on any target platform this crate could be built for.
pub unsafe trait Portable: Flat {}

/// Trait for casting portable type to/from native counterparts.
pub trait NativeCast: Portable + Copy {
    type Native: Copy;
    fn from_native(n: Self::Native) -> Self;
    fn to_native(&self) -> Self::Native;
}

pub use bool_::Bool;
pub use float::Float;
pub use int::Int;

/// Little-endian types.
pub mod le {
    use super::*;
    pub use float::le::*;
    pub use int::le::*;
}

/// Big-endian types.
pub mod be {
    use super::*;
    pub use float::be::*;
    pub use int::be::*;
}

pub mod traits {
    pub use super::{NativeCast, Portable};
}

macro_rules! derive_display {
    ($self:ty, $native:ty) => {
        impl core::fmt::Debug for $self {
            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
                <$native as core::fmt::Debug>::fmt(&self.to_native(), f)
            }
        }
        impl core::fmt::Display for $self {
            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
                <$native as core::fmt::Display>::fmt(&self.to_native(), f)
            }
        }
    };
}

pub(crate) use derive_display;