use std::cmp;
use std::fmt;
use std::ops;
use super::ALLOWED_ALPHA_FORMS;
#[derive(Hash, Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Serialize, Deserialize)]
pub enum Sign {
Pos,
Neg,
}
impl Sign {
pub fn combine(&self, other: &Sign) -> Sign {
if self == other {
Sign::Pos
} else {
Sign::Neg
}
}
}
impl fmt::Display for Sign {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Sign::Pos => write!(f, "+"),
Sign::Neg => write!(f, "-"),
}
}
}
impl ops::Neg for Sign {
type Output = Sign;
fn neg(self) -> Self::Output {
match self {
Sign::Neg => Sign::Pos,
Sign::Pos => Sign::Neg,
}
}
}
#[derive(Hash, Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone, Serialize, Deserialize)]
pub enum Index {
Zero,
One,
Two,
Three,
}
impl Index {
pub fn try_from_u8(x: u8) -> Result<Index, String> {
match x {
0 => Ok(Index::Zero),
1 => Ok(Index::One),
2 => Ok(Index::Two),
3 => Ok(Index::Three),
_ => Err(format!("{:?} is not a valid index", x)),
}
}
}
impl fmt::Display for Index {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Index::Zero => write!(f, "0"),
Index::One => write!(f, "1"),
Index::Two => write!(f, "2"),
Index::Three => write!(f, "3"),
}
}
}
#[derive(Hash, Eq, PartialEq, Debug, Copy, Clone, Serialize, Deserialize)]
pub enum Form {
Point,
Vector(Index),
Bivector(Index, Index),
Trivector(Index, Index, Index),
Quadrivector(Index, Index, Index, Index),
}
impl fmt::Display for Form {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Form::Point => write!(f, "p"),
Form::Vector(i) => write!(f, "{}", i),
Form::Bivector(i, j) => write!(f, "{}{}", i, j),
Form::Trivector(i, j, k) => write!(f, "{}{}{}", i, j, k),
Form::Quadrivector(i, j, k, l) => write!(f, "{}{}{}{}", i, j, k, l),
}
}
}
impl Form {
pub fn try_from_indices(ixs: &Vec<Index>) -> Result<Form, String> {
match ixs.len() {
0 => Ok(Form::Point),
1 => Ok(Form::Vector(ixs[0])),
2 => Ok(Form::Bivector(ixs[0], ixs[1])),
3 => Ok(Form::Trivector(ixs[0], ixs[1], ixs[2])),
4 => Ok(Form::Quadrivector(ixs[0], ixs[1], ixs[2], ixs[3])),
_ => Err(format!("Invalid component indices {:?}", ixs)),
}
}
pub fn as_vec(&self) -> Vec<Index> {
match *self {
Form::Point => vec![],
Form::Vector(i) => vec![i],
Form::Bivector(i, j) => vec![i, j],
Form::Trivector(i, j, k) => vec![i, j, k],
Form::Quadrivector(i, j, k, l) => vec![i, j, k, l],
}
}
}
impl cmp::Ord for Form {
fn cmp(&self, other: &Self) -> cmp::Ordering {
let i1 = ALLOWED_ALPHA_FORMS
.iter()
.position(|f| f == self)
.expect(&format!("{} is an invalid space-time Form", self));
let i2 = ALLOWED_ALPHA_FORMS
.iter()
.position(|f| f == other)
.expect(&format!("{} is an invalid space-time Form", other));
i1.cmp(&i2)
}
}
impl cmp::PartialOrd for Form {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}