use std::collections::HashMap;
use crate::mission::geometry::Instrument;
use crate::mission::site::Location;
#[derive(Debug, Default, Clone)]
pub struct MissionContext {
locations: HashMap<String, Location>,
instruments: HashMap<String, Instrument>,
}
impl MissionContext {
pub fn new() -> Self {
Self::default()
}
pub fn add_location(&mut self, alias: impl Into<String>, location: Location) {
self.locations.insert(alias.into(), location);
}
pub fn add_instrument(&mut self, alias: impl Into<String>, instrument: Instrument) {
self.instruments.insert(alias.into(), instrument);
}
pub fn with_location(mut self, alias: impl Into<String>, location: Location) -> Self {
self.add_location(alias, location);
self
}
pub fn with_instrument(mut self, alias: impl Into<String>, instrument: Instrument) -> Self {
self.add_instrument(alias, instrument);
self
}
pub fn location(&self, alias: &str) -> Option<&Location> {
self.locations.get(alias)
}
pub fn instrument(&self, alias: &str) -> Option<&Instrument> {
self.instruments.get(alias)
}
pub fn remove_location(&mut self, alias: &str) -> Option<Location> {
self.locations.remove(alias)
}
pub fn remove_instrument(&mut self, alias: &str) -> Option<Instrument> {
self.instruments.remove(alias)
}
pub fn locations(&self) -> impl Iterator<Item = (&String, &Location)> {
self.locations.iter()
}
pub fn instruments(&self) -> impl Iterator<Item = (&String, &Instrument)> {
self.instruments.iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mission::geometry::{Fov, LocalFrame};
use qtty::Quantity;
#[test]
fn empty_context_has_no_aliases() {
let ctx = MissionContext::new();
assert!(ctx.location("foo").is_none());
assert!(ctx.instrument("bar").is_none());
}
#[test]
fn add_and_lookup_round_trip() {
let frame = LocalFrame::new(Quantity::new(0.5), Quantity::new(0.3));
let loc = Location::new("VLBI-A", frame);
let inst = Instrument::new(
"cam",
Fov::Conical {
half_angle: Quantity::new(0.1),
},
);
let ctx = MissionContext::new()
.with_location("station-a", loc.clone())
.with_instrument("cam-1", inst.clone());
assert_eq!(ctx.location("station-a").unwrap().id, "VLBI-A");
assert_eq!(ctx.instrument("cam-1").unwrap().id, "cam");
}
#[test]
fn remove_returns_registered_object() {
let frame = LocalFrame::new(Quantity::new(0.5), Quantity::new(0.3));
let loc = Location::new("VLBI-A", frame);
let mut ctx = MissionContext::new();
ctx.add_location("a", loc);
assert!(ctx.remove_location("a").is_some());
assert!(ctx.remove_location("a").is_none());
}
}