use crate::data::Radial;
use crate::result::{Error, Result};
use std::fmt::{Debug, Display};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Sweep {
elevation_number: u8,
radials: Vec<Radial>,
}
impl Sweep {
pub fn new(elevation_number: u8, radials: Vec<Radial>) -> Self {
Self {
elevation_number,
radials,
}
}
pub fn from_radials(radials: Vec<Radial>) -> Vec<Self> {
let mut sweeps = Vec::new();
let mut sweep_elevation_number = None;
let mut sweep_radials = Vec::new();
for radial in radials {
if let Some(elevation_number) = sweep_elevation_number {
if elevation_number != radial.elevation_number() {
sweeps.push(Sweep::new(elevation_number, sweep_radials));
sweep_radials = Vec::new();
}
}
sweep_elevation_number = Some(radial.elevation_number());
sweep_radials.push(radial);
}
sweeps
}
pub fn elevation_number(&self) -> u8 {
self.elevation_number
}
pub fn radials(&self) -> &Vec<Radial> {
self.radials.as_ref()
}
pub fn merge(self, other: Self) -> Result<Self> {
if self.elevation_number != other.elevation_number {
return Err(Error::ElevationMismatchError);
}
let mut radials = self.radials;
radials.extend(other.radials);
radials.sort_by_key(|radial| radial.azimuth_number());
Ok(Self {
elevation_number: self.elevation_number,
radials,
})
}
}
impl Display for Sweep {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let (Some(first), Some(last)) = (self.radials.first(), self.radials.last()) {
write!(
f,
"Sweep ({:.1}-{:.1} deg, {} radials, {} deg spacing)",
first.azimuth_angle_degrees(),
last.azimuth_angle_degrees(),
self.radials.len(),
first.azimuth_spacing_degrees()
)
} else {
write!(f, "Sweep (no radials)")
}
}
}
impl Debug for Sweep {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sweep")
.field("elevation_number", &self.elevation_number())
.field("radials", &self.radials())
.finish()
}
}