use crate::Point;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
pub struct Zero;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
pub struct NonZero;
pub trait ZeroChoice:
Default
+ Clone
+ PartialEq
+ Eq
+ Copy
+ DecideZero<NonZero, Out = Self>
+ DecideZero<Zero, Out = Zero>
+ DecideZero<Self, Out = Self>
+ core::hash::Hash
+ Ord
+ PartialOrd
+ 'static
{
fn is_zero() -> bool;
fn cast_point<T, S, Z: ZeroChoice>(point: Point<T, S, Z>) -> Option<Point<T, S, Self>>;
}
impl ZeroChoice for Zero {
fn is_zero() -> bool {
true
}
fn cast_point<T, S, Z: ZeroChoice>(point: Point<T, S, Z>) -> Option<Point<T, S, Zero>> {
Some(point.mark_zero())
}
}
impl ZeroChoice for NonZero {
fn is_zero() -> bool {
false
}
fn cast_point<T, S, Z: ZeroChoice>(point: Point<T, S, Z>) -> Option<Point<T, S, Self>> {
point.non_zero()
}
}
pub trait DecideZero<ZZ> {
type Out: ZeroChoice;
}
impl<Z: ZeroChoice> DecideZero<Z> for Zero {
type Out = Zero;
}
impl<Z: ZeroChoice> DecideZero<Z> for NonZero {
type Out = Z;
}