pebbles 0.0.102

A unfinished webautomation framework for working with Firefox and the geckodriver.
Documentation
use crate::raise;
use crate::{PebblesError, PebblesErrorDetails};
use rand_distr::{Triangular, Distribution};

/// `Rect` is a struct that represents a rectangle.
///
/// It has four fields: `x`, `y`, `width`, and `height`.
/// `x` and `y` represent the coordinates of the top left corner of the rectangle.
/// `width` and `height` represent the dimensions of the rectangle.
pub struct Rect {
    pub x:i64,
    pub y:i64,
    pub width:i64,
    pub height:i64,
}

impl Rect {
    /// Returns a random point within the rectangle using a triangular distribution.
    ///
    /// The point is relative to the top left corner of the rectangle (i.e., local to the rectangle).
    /// The distribution is triangular with the mode at the center of the rectangle.
    ///
    /// # Errors
    ///
    /// Returns `PebblesError::MathError` if there is an error generating the triangular distribution.
    pub fn local_point(&self) -> Result<(i64, i64), PebblesError> {
        let mut rng = rand::thread_rng();
        let triangular_x = Triangular::new(0.0, self.width as f64, self.width as f64 / 2.0)
            .or_else(|error| raise!(PebblesError::MathError, format!(
                "Error while generating Triangular range: /
                {}", error)))?;
        let triangular_y = Triangular::new(0.0, self.height as f64, self.height as f64 / 2.0)
            .or_else(|error| raise!(PebblesError::MathError, format!(
                "Error while generating Triangular range: /
                {}", error)))?;
        Ok((triangular_x.sample(&mut rng) as i64, triangular_y.sample(&mut rng) as i64))
    }

    /// Returns a random point within the rectangle using a triangular distribution.
    ///
    /// The point is relative to the origin of the coordinate system (i.e., global).
    /// The distribution is triangular with the mode at the center of the rectangle.
    ///
    /// # Errors
    ///
    /// Returns `PebblesError::MathError` if there is an error generating the triangular distribution.
    pub fn world_point(&self) -> Result<(i64, i64), PebblesError> {
        let (x, y) = self.local_point()?;
        Ok((self.x + x, self.y + y))
    }

    pub fn overlaps(&self, other: &Rect) -> bool {
        let self_right = self.x + self.width;
        let self_bottom = self.y + self.height;
        let other_right = other.x + other.width;
        let other_bottom = other.y + other.height;
    
        if self.x < other_right && self_right > other.x && self.y < other_bottom && self_bottom > other.y {
            return true;
        }
    
        false
    }
}

impl std::fmt::Display for Rect {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{{x:{}, y:{}, width:{}, height:{}}}", self.x, self.y, self.width, self.height)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_local_point() {
        let rect = Rect {
            x: 0,
            y: 0,
            width: 10,
            height: 10,
        };

        let result = rect.local_point();
        assert!(result.is_ok());

        let point = result.unwrap();
        assert!(point.0 >= 0 && point.0 <= 10);
        assert!(point.1 >= 0 && point.1 <= 10);
    }

    #[test]
    fn test_world_point() {
        let rect = Rect {
            x: 5,
            y: 5,
            width: 10,
            height: 10,
        };

        let result = rect.world_point();
        assert!(result.is_ok());

        let point = result.unwrap();
        assert!(point.0 >= 5 && point.0 <= 15);
        assert!(point.1 >= 5 && point.1 <= 15);
    }
    #[test]
    fn test_overlaps() {
        let rect1 = Rect { x: 0, y: 0, width: 10, height: 10 };
        let rect2 = Rect { x: 5, y: 5, width: 10, height: 10 };
        let rect3 = Rect { x: 20, y: 20, width: 10, height: 10 };

        assert!(rect1.overlaps(&rect2), "Rect1 should overlap with Rect2");
        assert!(!rect1.overlaps(&rect3), "Rect1 should not overlap with Rect3");
    }
}