leodos_protocols/network/isl/
torus.rs1#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
3pub struct Point {
4 pub orb: u8,
6 pub sat: u8,
8}
9
10impl Point {
11 pub fn new(orb: u8, sat: u8) -> Self {
13 Self { orb, sat }
14 }
15}
16
17#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
19pub enum Direction {
20 North,
22 South,
24 East,
26 West,
28}
29
30impl Direction {
31 pub fn opposite(self) -> Self {
33 match self {
34 Self::North => Self::South,
35 Self::South => Self::North,
36 Self::East => Self::West,
37 Self::West => Self::East,
38 }
39 }
40}
41
42#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
44pub enum Hop {
45 Isl(Direction),
47 Ground,
49 Local,
51}
52
53#[derive(Debug, Copy, Clone)]
55pub struct Torus {
56 pub num_orbs: u8,
58 pub num_sats: u8,
60}
61
62impl Torus {
63 pub const fn new(num_orbs: u8, num_sats: u8) -> Self {
65 Self { num_orbs, num_sats }
66 }
67
68 pub fn neighbor(&self, point: Point, direction: Direction) -> Point {
70 match direction {
71 Direction::North => Point::new(point.orb, Self::prev(point.sat, self.num_sats)),
72 Direction::South => Point::new(point.orb, Self::next(point.sat, self.num_sats)),
73 Direction::East => Point::new(Self::next(point.orb, self.num_orbs), point.sat),
74 Direction::West => Point::new(Self::prev(point.orb, self.num_orbs), point.sat),
75 }
76 }
77
78 pub fn next(index: u8, modulus: u8) -> u8 {
82 if index == modulus - 1 { 0 } else { index + 1 }
83 }
84
85 pub fn prev(index: u8, modulus: u8) -> u8 {
87 if index == 0 { modulus - 1 } else { index - 1 }
88 }
89
90 pub fn distance(from: u8, to: u8, modulus: u8) -> u8 {
92 if to >= from {
93 to - from
94 } else {
95 modulus - from + to
96 }
97 }
98
99 pub fn next_sat(&self, p: Point) -> u8 {
101 Self::next(p.sat, self.num_sats)
102 }
103
104 pub fn prev_sat(&self, p: Point) -> u8 {
106 Self::prev(p.sat, self.num_sats)
107 }
108
109 pub fn next_orb(&self, p: Point) -> u8 {
111 Self::next(p.orb, self.num_orbs)
112 }
113
114 pub fn prev_orb(&self, p: Point) -> u8 {
116 Self::prev(p.orb, self.num_orbs)
117 }
118
119 pub fn distance_orb(&self, from: Point, to: Point) -> u8 {
121 Self::distance(from.orb, to.orb, self.num_orbs)
122 }
123
124 pub fn distance_sat(&self, from: Point, to: Point) -> u8 {
126 Self::distance(from.sat, to.sat, self.num_sats)
127 }
128
129 pub fn direction_to_sat(&self, from: Point, to: Point) -> Direction {
131 let north_dist = self.distance_sat(to, from);
132 let south_dist = self.distance_sat(from, to);
133 if north_dist < south_dist {
134 Direction::North
135 } else {
136 Direction::South
137 }
138 }
139
140 pub fn direction_to_orb(&self, from: Point, to: Point) -> Direction {
142 let west_dist = self.distance_orb(to, from);
143 let east_dist = self.distance_orb(from, to);
144 if west_dist < east_dist {
145 Direction::West
146 } else {
147 Direction::East
148 }
149 }
150}