engine_observables_api/
types.rs1use malloc_size_of_derive::MallocSizeOf;
10use serde::{Deserialize, Serialize};
11
12#[derive(
18 Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize,
19)]
20pub struct SourceNodeId(pub u64);
21
22#[derive(
27 Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize,
28)]
29pub struct SourceRange {
30 pub start: usize,
31 pub end: usize,
32}
33
34impl SourceRange {
35 pub fn new(start: usize, end: usize) -> Self {
36 Self { start, end }
37 }
38
39 pub fn is_empty(&self) -> bool {
40 self.end <= self.start
41 }
42
43 pub fn len(&self) -> usize {
44 self.end.saturating_sub(self.start)
45 }
46}
47
48#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
51pub struct Point {
52 pub x: f32,
53 pub y: f32,
54}
55
56impl Point {
57 pub fn new(x: f32, y: f32) -> Self {
58 Self { x, y }
59 }
60}
61
62#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
66pub struct Rect {
67 pub origin: Point,
68 pub width: f32,
69 pub height: f32,
70}
71
72impl Rect {
73 pub fn new(origin: Point, width: f32, height: f32) -> Self {
74 Self {
75 origin,
76 width,
77 height,
78 }
79 }
80
81 pub fn contains(&self, point: Point) -> bool {
82 point.x >= self.origin.x
83 && point.x < self.origin.x + self.width
84 && point.y >= self.origin.y
85 && point.y < self.origin.y + self.height
86 }
87}
88
89#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
93pub struct Lang(pub String);
94
95impl Lang {
96 pub fn new(tag: impl Into<String>) -> Self {
97 Self(tag.into())
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn rect_contains_inclusive_top_left_exclusive_bottom_right() {
107 let r = Rect::new(Point::new(10.0, 10.0), 100.0, 50.0);
108 assert!(r.contains(Point::new(10.0, 10.0)));
109 assert!(r.contains(Point::new(50.0, 30.0)));
110 assert!(!r.contains(Point::new(110.0, 10.0))); assert!(!r.contains(Point::new(50.0, 60.0))); assert!(!r.contains(Point::new(9.9, 30.0)));
113 }
114
115 #[test]
116 fn source_range_len_and_empty() {
117 assert_eq!(SourceRange::new(5, 10).len(), 5);
118 assert!(SourceRange::new(5, 5).is_empty());
119 assert!(SourceRange::new(10, 5).is_empty());
120 }
121
122 #[test]
123 fn source_node_id_round_trips_through_serde() {
124 let id = SourceNodeId(0xCAFE_BABE);
125 let json = serde_json::to_string(&id).unwrap();
126 let back: SourceNodeId = serde_json::from_str(&json).unwrap();
127 assert_eq!(back, id);
128 }
129}