use crate::space_weather::types::{SpaceWeatherExtrapolation, SpaceWeatherType};
use crate::time::Epoch;
use crate::utils::errors::BraheError;
pub trait SpaceWeatherProvider: Send + Sync {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn sw_type(&self) -> SpaceWeatherType;
fn is_initialized(&self) -> bool;
fn extrapolation(&self) -> SpaceWeatherExtrapolation;
fn mjd_min(&self) -> f64;
fn mjd_max(&self) -> f64;
fn mjd_last_observed(&self) -> f64;
fn mjd_last_daily_predicted(&self) -> f64;
fn mjd_last_monthly_predicted(&self) -> f64;
fn get_kp(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_kp_all(&self, mjd: f64) -> Result<[f64; 8], BraheError>;
fn get_kp_daily(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_ap(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_ap_all(&self, mjd: f64) -> Result<[f64; 8], BraheError>;
fn get_ap_daily(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_f107_observed(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_f107_adjusted(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_f107_obs_avg81(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_f107_adj_avg81(&self, mjd: f64) -> Result<f64, BraheError>;
fn get_sunspot_number(&self, mjd: f64) -> Result<u32, BraheError>;
fn get_last_kp(&self, mjd: f64, n: usize) -> Result<Vec<f64>, BraheError>;
fn get_last_ap(&self, mjd: f64, n: usize) -> Result<Vec<f64>, BraheError>;
fn get_last_daily_kp(&self, mjd: f64, n: usize) -> Result<Vec<f64>, BraheError>;
fn get_last_daily_ap(&self, mjd: f64, n: usize) -> Result<Vec<f64>, BraheError>;
fn get_last_f107(&self, mjd: f64, n: usize) -> Result<Vec<f64>, BraheError>;
fn get_last_kpap_epochs(&self, mjd: f64, n: usize) -> Result<Vec<Epoch>, BraheError>;
fn get_last_daily_epochs(&self, mjd: f64, n: usize) -> Result<Vec<Epoch>, BraheError>;
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
struct MockSpaceWeatherProvider {
len: usize,
}
impl SpaceWeatherProvider for MockSpaceWeatherProvider {
fn len(&self) -> usize {
self.len
}
fn sw_type(&self) -> SpaceWeatherType {
SpaceWeatherType::Static
}
fn is_initialized(&self) -> bool {
true
}
fn extrapolation(&self) -> SpaceWeatherExtrapolation {
SpaceWeatherExtrapolation::Hold
}
fn mjd_min(&self) -> f64 {
0.0
}
fn mjd_max(&self) -> f64 {
0.0
}
fn mjd_last_observed(&self) -> f64 {
0.0
}
fn mjd_last_daily_predicted(&self) -> f64 {
0.0
}
fn mjd_last_monthly_predicted(&self) -> f64 {
0.0
}
fn get_kp(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_kp_all(&self, _mjd: f64) -> Result<[f64; 8], BraheError> {
Ok([0.0; 8])
}
fn get_kp_daily(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_ap(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_ap_all(&self, _mjd: f64) -> Result<[f64; 8], BraheError> {
Ok([0.0; 8])
}
fn get_ap_daily(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_f107_observed(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_f107_adjusted(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_f107_obs_avg81(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_f107_adj_avg81(&self, _mjd: f64) -> Result<f64, BraheError> {
Ok(0.0)
}
fn get_sunspot_number(&self, _mjd: f64) -> Result<u32, BraheError> {
Ok(0)
}
fn get_last_kp(&self, _mjd: f64, n: usize) -> Result<Vec<f64>, BraheError> {
Ok(vec![0.0; n])
}
fn get_last_ap(&self, _mjd: f64, n: usize) -> Result<Vec<f64>, BraheError> {
Ok(vec![0.0; n])
}
fn get_last_daily_kp(&self, _mjd: f64, n: usize) -> Result<Vec<f64>, BraheError> {
Ok(vec![0.0; n])
}
fn get_last_daily_ap(&self, _mjd: f64, n: usize) -> Result<Vec<f64>, BraheError> {
Ok(vec![0.0; n])
}
fn get_last_f107(&self, _mjd: f64, n: usize) -> Result<Vec<f64>, BraheError> {
Ok(vec![0.0; n])
}
fn get_last_kpap_epochs(&self, mjd: f64, n: usize) -> Result<Vec<Epoch>, BraheError> {
let mut epochs = Vec::with_capacity(n);
for i in 0..n {
epochs.push(Epoch::from_mjd(
mjd - (i as f64 * 0.125),
crate::time::TimeSystem::UTC,
));
}
epochs.reverse();
Ok(epochs)
}
fn get_last_daily_epochs(&self, mjd: f64, n: usize) -> Result<Vec<Epoch>, BraheError> {
let mut epochs = Vec::with_capacity(n);
for i in 0..n {
epochs.push(Epoch::from_mjd(
mjd.floor() - i as f64,
crate::time::TimeSystem::UTC,
));
}
epochs.reverse();
Ok(epochs)
}
}
#[test]
fn test_space_weather_provider_is_empty_default() {
let empty_provider = MockSpaceWeatherProvider { len: 0 };
assert!(empty_provider.is_empty());
let non_empty_provider = MockSpaceWeatherProvider { len: 10 };
assert!(!non_empty_provider.is_empty());
let single_entry_provider = MockSpaceWeatherProvider { len: 1 };
assert!(!single_entry_provider.is_empty());
}
#[test]
fn test_mock_space_weather_provider_trait_methods() {
let provider = MockSpaceWeatherProvider { len: 5 };
assert_eq!(provider.len(), 5);
assert!(!provider.is_empty());
assert_eq!(provider.sw_type(), SpaceWeatherType::Static);
assert!(provider.is_initialized());
assert_eq!(provider.extrapolation(), SpaceWeatherExtrapolation::Hold);
assert_eq!(provider.mjd_min(), 0.0);
assert_eq!(provider.mjd_max(), 0.0);
assert_eq!(provider.mjd_last_observed(), 0.0);
assert_eq!(provider.mjd_last_daily_predicted(), 0.0);
assert_eq!(provider.mjd_last_monthly_predicted(), 0.0);
let test_mjd = 60000.0;
assert_eq!(provider.get_kp(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_kp_all(test_mjd).unwrap(), [0.0; 8]);
assert_eq!(provider.get_kp_daily(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_ap(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_ap_all(test_mjd).unwrap(), [0.0; 8]);
assert_eq!(provider.get_ap_daily(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_f107_observed(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_f107_adjusted(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_f107_obs_avg81(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_f107_adj_avg81(test_mjd).unwrap(), 0.0);
assert_eq!(provider.get_sunspot_number(test_mjd).unwrap(), 0);
}
}