Skip to main content

platform_data/
hybrid.rs

1use platform_num::LinkReference;
2
3#[derive(Debug, Clone, Copy, Hash, PartialOrd, PartialEq, Ord, Eq)]
4pub struct Hybrid<T> {
5    value: T,
6}
7
8impl<T: LinkReference> Hybrid<T> {
9    pub const fn new(value: T) -> Self {
10        Self::internal(value)
11    }
12
13    #[must_use]
14    pub fn half() -> T {
15        T::MAX / T::from_byte(2)
16    }
17
18    pub fn external(value: T) -> Self {
19        Self {
20            value: Self::extend_value(value),
21        }
22    }
23
24    pub const fn internal(value: T) -> Self {
25        Self { value }
26    }
27
28    fn extend_value(value: T) -> T {
29        (T::MAX - value).wrapping_add(&T::from_byte(1))
30    }
31
32    pub fn is_zero(&self) -> bool {
33        self.value == T::from_byte(0)
34    }
35
36    pub fn is_internal(&self) -> bool {
37        self.value < Self::half() // || self.value == T::default()
38    }
39
40    pub fn is_external(&self) -> bool {
41        !self.is_internal() || self.value == T::from_byte(0)
42    }
43
44    pub fn abs(&self) -> T {
45        self.value
46            .wrapping_add(&T::from_byte(1))
47            .wrapping_add(&T::MAX)
48    }
49
50    pub const fn as_inner(&self) -> T {
51        self.value
52    }
53}