use rand::distributions::Distribution;
use rand::{thread_rng, Rng};
use super::{
Area, HasPosition, HasSize, PlacedShape, Position, PositionRange, ProvidesArea,
ProvidesPlacedShape, ProvidesPosition, ProvidesSize, Size, SizeRange,
};
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct AreaRange {
position_range: PositionRange,
size_range: SizeRange,
}
impl AreaRange {
#[must_use]
pub fn new(position_range: PositionRange, size_range: SizeRange) -> Self {
Self {
position_range,
size_range,
}
}
}
impl Distribution<Area> for AreaRange {
fn sample<R>(&self, rng: &mut R) -> Area
where
R: Rng + ?Sized,
{
Area::new(rng.sample(self.position_range), rng.sample(self.size_range))
}
}
impl From<Area> for AreaRange {
fn from(area: Area) -> Self {
AreaRange::new(
PositionRange::from(*area.position()),
SizeRange::from(*area.size()),
)
}
}
impl ProvidesArea for AreaRange {
fn provide_area(&self) -> Area {
self.sample(&mut thread_rng())
}
}
impl ProvidesPlacedShape for AreaRange {
fn provide_placed_shape(&self) -> Box<dyn PlacedShape> {
Box::new(self.provide_area())
}
}
impl ProvidesPosition for AreaRange {
fn provide_position(&self) -> Position {
self.position_range.sample(&mut thread_rng())
}
}
impl ProvidesSize for AreaRange {
fn provide_size(&self) -> Size {
self.size_range.sample(&mut thread_rng())
}
}