StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.
| 1 | use std::{ |
| 2 | cmp::Ordering, |
| 3 | ops::{Add, AddAssign, Sub}, |
| 4 | }; |
| 5 | |
| 6 | /// A point within a document. The exact coordinate system (whether or not rows |
| 7 | /// are soft-wrapped, what the unit for characters is) is unspecified. |
| 8 | #[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash)] |
| 9 | pub struct Point { |
| 10 | pub row: u32, |
| 11 | pub column: u32, |
| 12 | } |
| 13 | |
| 14 | impl Point { |
| 15 | pub fn new(row: u32, column: u32) -> Self { |
| 16 | Point { row, column } |
| 17 | } |
| 18 | |
| 19 | pub fn zero() -> Self { |
| 20 | Point::new(0, 0) |
| 21 | } |
| 22 | |
| 23 | pub fn is_zero(&self) -> bool { |
| 24 | self.row == 0 && self.column == 0 |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | impl Add for Point { |
| 29 | type Output = Point; |
| 30 | |
| 31 | fn add(self, other: Self) -> Self::Output { |
| 32 | if other.row == 0 { |
| 33 | Point::new(self.row, self.column + other.column) |
| 34 | } else { |
| 35 | Point::new(self.row + other.row, other.column) |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | impl Sub for Point { |
| 41 | type Output = Point; |
| 42 | |
| 43 | fn sub(self, other: Self) -> Self::Output { |
| 44 | debug_assert!(other <= self); |
| 45 | |
| 46 | if self.row == other.row { |
| 47 | Point::new(0, self.column - other.column) |
| 48 | } else { |
| 49 | Point::new(self.row - other.row, self.column) |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | impl AddAssign<Self> for Point { |
| 55 | fn add_assign(&mut self, other: Self) { |
| 56 | if other.row == 0 { |
| 57 | self.column += other.column; |
| 58 | } else { |
| 59 | self.row += other.row; |
| 60 | self.column = other.column; |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | impl PartialOrd for Point { |
| 66 | fn partial_cmp(&self, other: &Point) -> Option<Ordering> { |
| 67 | Some(self.cmp(other)) |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | impl Ord for Point { |
| 72 | #[cfg(target_pointer_width = "64")] |
| 73 | fn cmp(&self, other: &Point) -> Ordering { |
| 74 | let a = (self.row as usize) << 32 | self.column as usize; |
| 75 | let b = (other.row as usize) << 32 | other.column as usize; |
| 76 | a.cmp(&b) |
| 77 | } |
| 78 | |
| 79 | #[cfg(target_pointer_width = "32")] |
| 80 | fn cmp(&self, other: &Point) -> Ordering { |
| 81 | match self.row.cmp(&other.row) { |
| 82 | Ordering::Equal => self.column.cmp(&other.column), |
| 83 | comparison => comparison, |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 |