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