use crate::astro::moon::LunarPosition;
use crate::astro::planets::{Planet, PlanetEvent, PlanetPosition};
use crate::astro::sun::SolarPosition;
use crate::astro::{Location, moon, planets, sun};
use chrono::DateTime;
use chrono_tz::Tz;
#[derive(Debug, Clone)]
pub struct CachedEvents {
pub reference: DateTime<Tz>,
pub entries: Vec<(DateTime<Tz>, &'static str)>,
}
#[derive(Debug, Clone, Copy)]
pub struct CachedPositions {
pub timestamp: DateTime<Tz>,
pub sun: SolarPosition,
pub moon: LunarPosition,
}
impl CachedPositions {
pub fn new(location: &Location, timestamp: &DateTime<Tz>) -> Self {
Self {
timestamp: *timestamp,
sun: sun::solar_position(location, timestamp),
moon: moon::lunar_position(location, timestamp),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct CachedPlanet {
pub planet: Planet,
pub position: PlanetPosition,
pub rise: Option<DateTime<Tz>>,
pub set: Option<DateTime<Tz>>,
}
#[derive(Debug, Clone)]
pub struct CachedPlanets {
pub timestamp: DateTime<Tz>,
pub entries: Vec<CachedPlanet>,
}
impl CachedPlanets {
pub fn new(location: &Location, timestamp: &DateTime<Tz>) -> Self {
let entries = Planet::ALL
.iter()
.map(|&planet| CachedPlanet {
planet,
position: planets::planet_position(planet, location, timestamp),
rise: planets::planet_event_time(planet, location, timestamp, PlanetEvent::Rise),
set: planets::planet_event_time(planet, location, timestamp, PlanetEvent::Set),
})
.collect();
Self {
timestamp: *timestamp,
entries,
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum MoonAltitudeTrend {
Down,
Up,
}
#[derive(Debug, Clone, Copy)]
pub struct CachedMoonDetails {
pub timestamp: DateTime<Tz>,
pub moon: LunarPosition,
pub altitude_trend: MoonAltitudeTrend,
}
impl CachedMoonDetails {
pub fn from_positions(location: &Location, positions: &CachedPositions) -> Self {
let altitude_trend = determine_moon_trend(location, &positions.timestamp, positions.moon);
Self {
timestamp: positions.timestamp,
moon: positions.moon,
altitude_trend,
}
}
}
fn determine_moon_trend(
_location: &Location,
_timestamp: &DateTime<Tz>,
base: LunarPosition,
) -> MoonAltitudeTrend {
if base.altitude >= 0.0 {
MoonAltitudeTrend::Up
} else {
MoonAltitudeTrend::Down
}
}