Skip to main content

platform_data/
constants.rs

1use std::ops::RangeInclusive;
2
3use crate::{Hybrid, LinkType};
4
5#[derive(Clone, Eq, PartialEq, Debug)]
6pub struct LinksConstants<T: LinkType> {
7    pub index_part: T,
8    pub source_part: T,
9    pub target_part: T,
10    pub null: T,
11    pub r#continue: T,
12    pub r#break: T,
13    pub skip: T,
14    pub any: T,
15    pub itself: T,
16    pub error: T,
17    pub internal_range: RangeInclusive<T>,
18    pub external_range: Option<RangeInclusive<T>>,
19}
20
21impl<T: LinkType> LinksConstants<T> {
22    fn default_target_part() -> T {
23        T::funty(2)
24    }
25
26    pub fn full_new(
27        target_part: T,
28        internal: RangeInclusive<T>,
29        external: Option<RangeInclusive<T>>,
30    ) -> Self {
31        Self {
32            index_part: T::funty(0),
33            source_part: T::funty(1),
34            target_part,
35            null: T::funty(0),
36            r#continue: *internal.end(),
37            r#break: *internal.end() - T::funty(1),
38            skip: *internal.end() - T::funty(2),
39            any: *internal.end() - T::funty(3),
40            itself: *internal.end() - T::funty(4),
41            error: *internal.end() - T::funty(5),
42            internal_range: *internal.start()..=*internal.end() - T::funty(6),
43            external_range: external,
44        }
45    }
46
47    // TODO: enough for now
48    pub fn via_external(target_part: T, external: bool) -> Self {
49        Self::full_new(
50            target_part,
51            Self::default_internal(external),
52            Self::default_external(external),
53        )
54    }
55
56    pub fn via_ranges(internal: RangeInclusive<T>, external: Option<RangeInclusive<T>>) -> Self {
57        Self::full_new(Self::default_target_part(), internal, external)
58    }
59
60    #[must_use]
61    pub fn via_only_external(external: bool) -> Self {
62        Self::via_external(Self::default_target_part(), external)
63    }
64
65    #[must_use]
66    pub fn external() -> Self {
67        Self::via_only_external(true)
68    }
69
70    #[must_use]
71    pub fn internal() -> Self {
72        Self::via_only_external(false)
73    }
74
75    #[must_use]
76    pub fn new() -> Self {
77        Self::internal()
78    }
79
80    fn default_internal(external: bool) -> RangeInclusive<T> {
81        if external {
82            T::funty(1)..=Hybrid::half()
83        } else {
84            T::funty(1)..=T::MAX
85        }
86    }
87
88    fn default_external(external: bool) -> Option<RangeInclusive<T>> {
89        if external {
90            Some(Hybrid::half()..=T::MAX)
91        } else {
92            None
93        }
94    }
95
96    pub fn is_internal(&self, address: T) -> bool {
97        self.internal_range.contains(&address)
98    }
99
100    pub fn is_external(&self, address: T) -> bool {
101        self.external_range
102            .clone()
103            .is_some_and(|range| range.contains(&address))
104    }
105
106    pub fn is_reference(&self, address: T) -> bool {
107        self.is_internal(address) || self.is_external(address)
108    }
109}
110
111impl<T: LinkType> Default for LinksConstants<T> {
112    fn default() -> Self {
113        Self::new()
114    }
115}