#![cfg_attr(feature = "nightly", feature(try_from))]
use std::error::Error;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::ops::{Deref, DerefMut};
#[cfg(feature = "nightly")]
use std::convert::TryFrom;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[doc(hidden)]
pub mod math;
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug, Default)]
#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
pub struct Uf32(f32);
impl Uf32 {
pub fn try_new(value: f32) -> Result<Uf32, InvalidNumberError> {
if value > 0f32 {
Ok(Uf32(value))
} else {
Err(InvalidNumberError(value))
}
}
}
#[cfg(not(feature="nightly"))]
pub trait TryInto : Sized {
fn try_into(self) -> Result<Uf32, InvalidNumberError>;
}
#[cfg(not(feature="nightly"))]
impl TryInto for f32 {
fn try_into(self) -> Result<Uf32, InvalidNumberError> {
Uf32::try_new(self)
}
}
impl Display for Uf32 {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", &self.0)
}
}
impl Deref for Uf32 {
type Target = f32;
fn deref(&self) -> &<Self as Deref>::Target {
&self.0
}
}
impl DerefMut for Uf32 {
fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
&mut self.0
}
}
#[cfg(feature="nightly")]
impl TryFrom<f32> for Uf32 {
type Error = InvalidNumberError;
fn try_from(value: f32) -> Result<Self, <Self as TryFrom<f32>>::Error> {
Uf32::try_new(value)
}
}
#[derive(Clone, Copy, Debug)]
pub struct InvalidNumberError(f32);
impl Display for InvalidNumberError {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{} is invalid for a Uf32.", &self)
}
}
impl Error for InvalidNumberError {}
#[cfg(tests)]
mod tests {
use crate::*;
#[test]
fn it_works() {
let a = Uf32::try_new(1.0).unwrap();
let b = Uf32::try_new(2.0).unwrap();
assert_eq!(a + &b, Uf32::try_new(3.0).unwrap());
}
}