use crate::error::Error;
use crate::float::{FloatPolicy, FloatRepr};
use crate::key::Key;
use num_traits02 as nt02;
use ordered_float2 as of2;
use serde::{de, ser};
use std::cmp;
use std::fmt;
use std::hash;
#[derive(Clone, Copy)]
pub struct OrderedFloat<T>(pub T);
impl<T> fmt::Debug for OrderedFloat<T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, fmt)
}
}
impl FloatRepr<f32> for OrderedFloat<f32> {
fn serialize(float: f32) -> Result<Self, Error> {
Ok(OrderedFloat(float))
}
fn visit<'de, V>(&self, visitor: V) -> Result<V::Value, Error>
where
V: de::Visitor<'de>,
{
visitor.visit_f32(self.0)
}
}
impl FloatRepr<f64> for OrderedFloat<f64> {
fn serialize(float: f64) -> Result<Self, Error> {
Ok(OrderedFloat(float))
}
fn visit<'de, V>(&self, visitor: V) -> Result<V::Value, Error>
where
V: de::Visitor<'de>,
{
visitor.visit_f64(self.0)
}
}
impl<T> serde::Serialize for OrderedFloat<T>
where
T: serde::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl<T> PartialEq for OrderedFloat<T>
where
T: nt02::Float,
{
fn eq(&self, other: &Self) -> bool {
of2::OrderedFloat(self.0) == of2::OrderedFloat(other.0)
}
}
impl<T> Eq for OrderedFloat<T> where T: nt02::Float {}
impl<T> PartialOrd for OrderedFloat<T>
where
T: nt02::Float,
{
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(of2::OrderedFloat(self.0).cmp(&of2::OrderedFloat(other.0)))
}
}
impl<T> cmp::Ord for OrderedFloat<T>
where
T: nt02::Float,
{
fn cmp(&self, other: &Self) -> cmp::Ordering {
of2::OrderedFloat(self.0).cmp(&of2::OrderedFloat(other.0))
}
}
impl<T> hash::Hash for OrderedFloat<T>
where
T: nt02::Float,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
of2::OrderedFloat(self.0).hash(state)
}
}
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct OrderedFloatPolicy(());
impl FloatPolicy for OrderedFloatPolicy {
type F32 = OrderedFloat<f32>;
type F64 = OrderedFloat<f64>;
}
pub fn to_key_with_ordered_float<T>(value: &T) -> Result<Key<OrderedFloatPolicy>, Error>
where
T: ser::Serialize,
{
crate::ser::to_key_with_policy::<T, OrderedFloatPolicy>(value)
}