1use crate::LinkType;
2
3#[derive(Debug, Clone, Copy, Hash, PartialOrd, PartialEq, Ord, Eq)]
4pub struct Hybrid<T> {
5 value: T,
6}
7
8impl<T: LinkType> 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::funty(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::funty(1))
30 }
31
32 pub fn is_zero(&self) -> bool {
33 self.value == T::funty(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::funty(0)
42 }
43
44 pub fn abs(&self) -> T {
45 self.value.wrapping_add(T::funty(1)).wrapping_add(T::MAX)
46 }
47
48 pub const fn as_inner(&self) -> T {
49 self.value
50 }
51}