interp1d 0.2.0

A simple, lightweight interpolation library written in Rust.
Documentation
use std::{fmt::Display, ops::{Add, Sub, Div, Mul}};

use num_traits::{Float, PrimInt, Num, NumOps, NumRef, ToPrimitive, One, Zero};
use crate::error::InterpError;

use super::error::Result;

pub trait InterpNum: Num + NumOps + NumRef + PartialOrd + Display + ToPrimitive + Copy {}
pub trait InterpFloat: Mul<Output=Self> + Add<Output=Self> + Sub<Output=Self> + Div<Output=Self> + One + Zero + Copy {}

impl<Q: Num + NumOps + NumRef + PartialOrd + Display + ToPrimitive + Copy> InterpNum for Q {}
impl<Q: Mul<Output=Self> + Add<Output=Self> + Sub<Output=Self> + Div<Output=Self> + One + Zero + Copy> InterpFloat for Q {}

#[derive(Debug, Clone, Copy)]
pub struct Pair<T: Num, U: InterpFloat> {
    pub(crate) x: T,
    pub(crate) y: U,
}

impl<T: InterpNum, U: InterpFloat> PartialOrd for Pair<T, U> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.x.partial_cmp(&other.x)
    }
}

impl<T: InterpNum, U: InterpFloat> Eq for Pair<T, U> { }

impl<T: InterpNum, U: InterpFloat> PartialEq for Pair<T, U> {
    fn eq(&self, other: &Self) -> bool {
        self.x.eq(&other.x)
    }
}

impl<T: Float + InterpNum, U: InterpFloat> Pair<T, U> {
    pub(crate) fn from_float(pair: (T, U)) -> Result<Pair<T, U>> {
        if !pair.0.is_finite() { return Err(InterpError::InvalidData) }
        Ok(Pair { x: pair.0, y: pair.1 })
    }
}

impl<T: PrimInt + InterpNum, U: InterpFloat> Pair<T, U> {
    pub(crate) fn from_int(pair: (T, U)) -> Pair<T, U> {
        Pair { x: pair.0, y: pair.1 }
    }
}