conjure_object/
double_key.rs

1// Copyright 2021 Palantir Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//! Support for double collection keys.
15use ordered_float::OrderedFloat;
16use serde::{Deserialize, Deserializer, Serialize, Serializer};
17use std::cmp::Ordering;
18use std::fmt::{self, Display, Formatter};
19use std::hash::{Hash, Hasher};
20use std::ops::{Deref, DerefMut};
21
22/// A wrapper type allowing `f64` to be used as a key in collection types.
23///
24/// Conjure allows `map<double, T>` and `set<double>`, but Rust's `f64` type does not implement `Eq` and `Ord`,
25/// preventing the direct translations of `BTreeMap<f64, T>` and `BTreeSet<f64>` from compiling. This wrapper type is
26/// used to provide suitable trait implementations. The code generated by `conjure-codegen` will use this type,
27/// resulting in `BTreeMap<DoubleKey<f64>, T>` and `BTreeSet<DoubleKey<f64>>`.
28///
29/// All trait implementations delegate directly to the inner type, with the exception of the `PartialEq`, `Eq`,
30/// `PartialOrd`, and `Ord` methods.
31#[derive(Debug, Copy, Clone, Default)]
32pub struct DoubleKey(pub f64);
33
34impl Display for DoubleKey {
35    #[inline]
36    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
37        self.0.fmt(f)
38    }
39}
40
41impl Deref for DoubleKey {
42    type Target = f64;
43
44    #[inline]
45    fn deref(&self) -> &Self::Target {
46        &self.0
47    }
48}
49
50impl DerefMut for DoubleKey {
51    #[inline]
52    fn deref_mut(&mut self) -> &mut Self::Target {
53        &mut self.0
54    }
55}
56
57impl PartialOrd for DoubleKey {
58    #[inline]
59    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
60        Some(self.cmp(other))
61    }
62}
63
64impl PartialEq for DoubleKey {
65    #[inline]
66    fn eq(&self, other: &Self) -> bool {
67        OrderedFloat(self.0) == OrderedFloat(other.0)
68    }
69}
70
71impl Ord for DoubleKey {
72    #[inline]
73    fn cmp(&self, other: &Self) -> Ordering {
74        OrderedFloat(self.0).cmp(&OrderedFloat(other.0))
75    }
76}
77
78impl Eq for DoubleKey {}
79
80impl Hash for DoubleKey {
81    #[inline]
82    fn hash<H>(&self, state: &mut H)
83    where
84        H: Hasher,
85    {
86        OrderedFloat(self.0).hash(state)
87    }
88}
89
90impl<'de> Deserialize<'de> for DoubleKey {
91    #[inline]
92    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93    where
94        D: Deserializer<'de>,
95    {
96        f64::deserialize(deserializer).map(DoubleKey)
97    }
98}
99
100impl Serialize for DoubleKey {
101    #[inline]
102    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103    where
104        S: Serializer,
105    {
106        self.0.serialize(serializer)
107    }
108}