use std::fmt::Display;
use serde::Serialize;
use crate::Observer;
#[derive(Debug, Clone, Copy, Serialize)]
pub struct Telescope {
pub diameter: f64,
pub obscuration: Option<f64>,
}
impl Default for Telescope {
fn default() -> Self {
Self {
diameter: 1f64,
obscuration: Default::default(),
}
}
}
impl Display for Telescope {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(obscuration) = self.obscuration {
write!(
f,
"Telescope: {}m diameter ({}m diameter obscuration), {:.3}m^2 collection area",
self.diameter,
obscuration,
self.area()
)
} else {
write!(
f,
"Telescope: {}m diameter, {:.3}m^2 collection area",
self.diameter,
self.area()
)
}
}
}
pub struct TelescopeBuilder {
diameter: f64,
obscuration: Option<f64>,
}
impl Telescope {
pub fn new(diameter: f64) -> TelescopeBuilder {
TelescopeBuilder {
diameter,
obscuration: None,
}
}
}
impl TelescopeBuilder {
pub fn obscuration(mut self, obscuration: f64) -> Self {
self.obscuration = Some(obscuration);
self
}
pub fn build(self) -> Telescope {
Telescope {
diameter: self.diameter,
obscuration: self.obscuration,
..Default::default()
}
}
}
impl Observer for Telescope {
fn diameter(&self) -> f64 {
self.diameter
}
fn inside_pupil(&self, x: f64, y: f64) -> bool {
let r_outer = self.diameter * 0.5;
let r_inner = self.obscuration.unwrap_or_default();
let r = x.hypot(y);
r >= r_inner && r <= r_outer
}
}