starfall/astronomy/moon/constraints/
mod.rs

1use rand::prelude::*;
2
3use crate::astronomy::host_star::HostStar;
4use crate::astronomy::moon::constants::*;
5use crate::astronomy::moon::error::Error;
6use crate::astronomy::moon::Moon;
7use crate::astronomy::planet::Planet;
8
9/// Constraints for creating a moon.
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct Constraints {
12  /// The minimum mass, in Mmoon.
13  pub minimum_mass: Option<f64>,
14  /// The maximum mass, in Mmoon.
15  pub maximum_mass: Option<f64>,
16}
17
18impl Constraints {
19  /// Generate.
20  #[named]
21  pub fn generate<R: Rng + ?Sized>(
22    &self,
23    rng: &mut R,
24    host_star: &HostStar,
25    star_distance: f64,
26    planet: &Planet,
27    planet_distance: f64,
28  ) -> Result<Moon, Error> {
29    trace_enter!();
30    trace_var!(host_star);
31    trace_var!(star_distance);
32    trace_var!(planet);
33    trace_var!(planet_distance);
34    let minimum_mass = self.minimum_mass.unwrap_or(MINIMUM_MASS);
35    trace_var!(minimum_mass);
36    let maximum_mass = self.maximum_mass.unwrap_or(MAXIMUM_MASS);
37    trace_var!(maximum_mass);
38    let mass = rng.gen_range(minimum_mass..maximum_mass);
39    trace_var!(mass);
40    let result = Moon::from_environment(mass, host_star, star_distance, planet, planet_distance)?;
41    trace_var!(result);
42    trace_exit!();
43    Ok(result)
44  }
45}
46
47impl Default for Constraints {
48  /// No constraints, just let it all hang out.
49  fn default() -> Self {
50    let minimum_mass = None;
51    let maximum_mass = None;
52    Self {
53      minimum_mass,
54      maximum_mass,
55    }
56  }
57}
58
59#[cfg(test)]
60pub mod test {
61
62  use crate::astronomy::host_star::constraints::Constraints as HostStarConstraints;
63  use crate::astronomy::planet::constraints::Constraints as PlanetConstraints;
64  use rand::prelude::*;
65
66  use super::*;
67  use crate::test::*;
68
69  #[named]
70  #[test]
71  pub fn test_generate() -> Result<(), Error> {
72    init();
73    trace_enter!();
74    let mut rng = thread_rng();
75    trace_var!(rng);
76    let host_star = &HostStarConstraints::habitable().generate(&mut rng)?;
77    trace_var!(host_star);
78    let habitable_zone = host_star.get_habitable_zone();
79    trace_var!(habitable_zone);
80    let star_distance = rng.gen_range(habitable_zone.0..habitable_zone.1);
81    trace_var!(star_distance);
82    let planet = &PlanetConstraints::habitable().generate(&mut rng, &host_star, star_distance)?;
83    trace_var!(planet);
84    let moon = &Constraints::default().generate(&mut rng, &host_star, star_distance, &planet, 400_000.0)?;
85    trace_var!(moon);
86    print_var!(moon);
87    trace_exit!();
88    Ok(())
89  }
90}