1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#[cfg(feature = "ordered-float")]
pub use self::ordered_float::{to_key_with_ordered_float, OrderedFloat, OrderedFloatPolicy};
use crate::error::Error;
use serde::de;

mod float_policy;
mod float_repr;
#[cfg(feature = "ordered-float")]
mod ordered_float;

pub use self::float_policy::FloatPolicy;
pub use self::float_repr::FloatRepr;

/// An uninhabitable type for float policies that cannot produce a value of the
/// corresponding type. This is used by [RejectFloatPolicy].
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum NeverFloat {}

impl FloatRepr<f32> for NeverFloat {
    fn serialize(_: f32) -> Result<Self, Error> {
        Err(Error::UnsupportedType("f32"))
    }

    fn visit<'de, V>(&self, _: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        Err(Error::UnsupportedType("f32"))
    }
}

impl FloatRepr<f64> for NeverFloat {
    fn serialize(_: f64) -> Result<Self, Error> {
        Err(Error::UnsupportedType("f64"))
    }

    fn visit<'de, V>(&self, _: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        Err(Error::UnsupportedType("f64"))
    }
}

impl serde::Serialize for NeverFloat {
    fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        // Note: type is uninhabitable, so this impl can never be reached.
        unreachable!()
    }
}

/// A float serialization policy which rejects any attempt to serialize a float
/// with an error. This policy is used by the [to_key] function.
///
/// [to_key]: crate::to_key
///
/// # Examples
///
/// ```rust
/// use serde_hashkey::{Key, Float, to_key};
///
/// # fn main() -> Result<(), serde_hashkey::Error> {
/// assert!(to_key(&"John Doe").is_ok());
/// assert!(to_key(&42.42f32).is_err());
/// # Ok(()) }
/// ```
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct RejectFloatPolicy(());

impl FloatPolicy for RejectFloatPolicy {
    type F32 = NeverFloat;
    type F64 = NeverFloat;
}