platform_data/
constants.rs1use 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 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}