serde.rs (2103B)
1 /// Unit tests. 2 #[cfg(test)] 3 mod tests; 4 use crate::{Ratio, try_from_str}; 5 use core::{ 6 fmt::{self, Formatter}, 7 marker::PhantomData, 8 ops::Mul, 9 str::FromStr, 10 }; 11 use num_integer::Integer; 12 use num_traits::Pow; 13 use serde::de::{self, Deserialize, Deserializer, Unexpected, Visitor}; 14 /// Wrapper around a `num_rational::Ratio` that 15 /// deserializes a JSON string representing a rational number in 16 /// fractional or decimal notation to a Ratio<T>. 17 #[derive(Clone, Copy, Debug)] 18 pub struct Rational<T>(pub Ratio<T>); 19 impl<'de, T> Deserialize<'de> for Rational<T> 20 where 21 T: Clone 22 + From<u8> 23 + FromStr 24 + Integer 25 + for<'a> Mul<&'a T, Output = T> 26 + Pow<usize, Output = T>, 27 { 28 #[inline] 29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 30 where 31 D: Deserializer<'de>, 32 { 33 /// Visitor used to deserialize a JSON string into a Rational. 34 struct RationalVisitor<T> { 35 /// Does not own nor drop a `T`. 36 _x: PhantomData<fn() -> T>, 37 } 38 impl<T> Visitor<'_> for RationalVisitor<T> 39 where 40 T: Clone 41 + From<u8> 42 + FromStr 43 + Integer 44 + for<'a> Mul<&'a T, Output = T> 45 + Pow<usize, Output = T>, 46 { 47 type Value = Rational<T>; 48 fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { 49 formatter.write_str("struct Rational") 50 } 51 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 52 where 53 E: de::Error, 54 { 55 try_from_str(v).map_or_else( 56 |_| { 57 Err(E::invalid_value( 58 Unexpected::Str(v), 59 &"a rational number in fraction or decimal notation", 60 )) 61 }, 62 |val| Ok(Rational(val)), 63 ) 64 } 65 } 66 deserializer.deserialize_str(RationalVisitor { _x: PhantomData }) 67 } 68 }