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() }
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}