use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
#[derive(
Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize,
)]
pub struct SourceNodeId(pub u64);
#[derive(
Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize,
)]
pub struct SourceRange {
pub start: usize,
pub end: usize,
}
impl SourceRange {
pub fn new(start: usize, end: usize) -> Self {
Self { start, end }
}
pub fn is_empty(&self) -> bool {
self.end <= self.start
}
pub fn len(&self) -> usize {
self.end.saturating_sub(self.start)
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct Point {
pub x: f32,
pub y: f32,
}
impl Point {
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct Rect {
pub origin: Point,
pub width: f32,
pub height: f32,
}
impl Rect {
pub fn new(origin: Point, width: f32, height: f32) -> Self {
Self {
origin,
width,
height,
}
}
pub fn contains(&self, point: Point) -> bool {
point.x >= self.origin.x
&& point.x < self.origin.x + self.width
&& point.y >= self.origin.y
&& point.y < self.origin.y + self.height
}
}
#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct Lang(pub String);
impl Lang {
pub fn new(tag: impl Into<String>) -> Self {
Self(tag.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rect_contains_inclusive_top_left_exclusive_bottom_right() {
let r = Rect::new(Point::new(10.0, 10.0), 100.0, 50.0);
assert!(r.contains(Point::new(10.0, 10.0)));
assert!(r.contains(Point::new(50.0, 30.0)));
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)));
}
#[test]
fn source_range_len_and_empty() {
assert_eq!(SourceRange::new(5, 10).len(), 5);
assert!(SourceRange::new(5, 5).is_empty());
assert!(SourceRange::new(10, 5).is_empty());
}
#[test]
fn source_node_id_round_trips_through_serde() {
let id = SourceNodeId(0xCAFE_BABE);
let json = serde_json::to_string(&id).unwrap();
let back: SourceNodeId = serde_json::from_str(&json).unwrap();
assert_eq!(back, id);
}
}