use crate::conventions::LorentzianMetric;
use crate::errors::MetricError;
use crate::types::Metric;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WestCoastMetric(Metric);
impl WestCoastMetric {
pub const MINKOWSKI_4D: Self = Self(Metric::Minkowski(4));
pub const MINKOWSKI_3D: Self = Self(Metric::Minkowski(3));
pub fn new(metric: Metric) -> Result<Self, MetricError> {
let dim = metric.dimension();
if dim < 2 {
return Err(MetricError::invalid_dimension(
"Lorentzian metric requires at least 2 dimensions",
));
}
if metric.sign_of_sq(0) != 1 {
return Err(MetricError::sign_convention_mismatch(
"West Coast convention requires time (index 0) to have sign +1",
));
}
for i in 1..dim {
let sign = metric.sign_of_sq(i);
if sign != -1 && sign != 0 {
return Err(MetricError::sign_convention_mismatch(
"West Coast convention requires space dimensions to have sign -1",
));
}
}
Ok(Self(metric))
}
pub fn from_east_coast(metric: Metric) -> Result<Self, MetricError> {
let flipped = metric.flip_time_space();
Self::new(flipped)
}
pub fn new_nd(dim: usize) -> Result<Self, MetricError> {
if dim < 2 {
return Err(MetricError::invalid_dimension(
"Lorentzian metric requires at least 2 dimensions",
));
}
if dim > 64 {
return Err(MetricError::invalid_dimension(
"dimension exceeds bitmask capacity (max 64)",
));
}
Ok(Self(Metric::Minkowski(dim)))
}
pub fn inner(&self) -> &Metric {
&self.0
}
}
impl LorentzianMetric for WestCoastMetric {
fn as_metric(&self) -> &Metric {
&self.0
}
fn into_metric(self) -> Metric {
self.0
}
fn minkowski_4d() -> Self {
Self::MINKOWSKI_4D
}
fn minkowski_3d() -> Self {
Self::MINKOWSKI_3D
}
fn time_sign(&self) -> i32 {
1 }
fn space_sign(&self) -> i32 {
-1 }
fn is_east_coast(&self) -> bool {
false
}
fn is_west_coast(&self) -> bool {
true
}
}