@@ -15,7 +15,7 @@ use std::fmt;
1515use std:: io;
1616use std:: mem;
1717use unreachable:: unreachable;
18- use num_traits:: { Bounded , Float , FromPrimitive , One , ToPrimitive , Zero } ;
18+ use num_traits:: { Bounded , Float , FromPrimitive , Num , One , ToPrimitive , Zero } ;
1919
2020/// A wrapper around Floats providing an implementation of Ord and Hash.
2121///
@@ -621,6 +621,37 @@ impl<T: Float + ToPrimitive> ToPrimitive for NotNaN<T> {
621621 fn to_f64 ( & self ) -> Option < f64 > { self . 0 . to_f64 ( ) }
622622}
623623
624+ /// An error indicating a parse error from a string for `NotNaN`.
625+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
626+ pub enum ParseNotNaNError < E > {
627+ /// A plain parse error from the underlying float type.
628+ ParseFloatError ( E ) ,
629+ /// The parsed float value resulted in a NaN.
630+ IsNaN ,
631+ }
632+
633+ impl < E : fmt:: Debug > Error for ParseNotNaNError < E > {
634+ fn description ( & self ) -> & str {
635+ return "Error parsing a not-NaN floating point value" ;
636+ }
637+ }
638+
639+ impl < E : fmt:: Debug > fmt:: Display for ParseNotNaNError < E > {
640+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
641+ <Self as fmt:: Debug >:: fmt ( self , f)
642+ }
643+ }
644+
645+ impl < T : Float + Num > Num for NotNaN < T > {
646+ type FromStrRadixErr = ParseNotNaNError < T :: FromStrRadixErr > ;
647+
648+ fn from_str_radix ( src : & str , radix : u32 ) -> Result < Self , Self :: FromStrRadixErr > {
649+ T :: from_str_radix ( src, radix)
650+ . map_err ( |err| ParseNotNaNError :: ParseFloatError ( err) )
651+ . and_then ( |n| NotNaN :: new ( n) . map_err ( |_| ParseNotNaNError :: IsNaN ) )
652+ }
653+ }
654+
624655#[ cfg( feature = "serde" ) ]
625656mod impl_serde {
626657 extern crate serde;
0 commit comments