messagepack_core/encode/
float.rs1use super::{Encode, Result};
4use crate::{formats::Format, io::IoWrite};
5
6impl Encode for f32 {
7 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
8 writer.write(&Format::Float32.as_slice())?;
9 writer.write(&self.to_be_bytes())?;
10 Ok(5)
11 }
12}
13
14impl Encode for f64 {
15 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
16 writer.write(&Format::Float64.as_slice())?;
17 writer.write(&self.to_be_bytes())?;
18 Ok(9)
19 }
20}
21
22fn is_exactly_representable(x: f64) -> bool {
23 x.is_finite() && (x as f32) as f64 == x
24}
25
26#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
28pub enum EncodeMinimizeFloat {
29 F32(f32),
31 F64(f64),
33}
34
35impl From<f32> for EncodeMinimizeFloat {
36 fn from(value: f32) -> Self {
37 EncodeMinimizeFloat::F32(value)
38 }
39}
40
41impl From<f64> for EncodeMinimizeFloat {
42 fn from(value: f64) -> Self {
43 EncodeMinimizeFloat::F64(value)
44 }
45}
46
47impl Encode for EncodeMinimizeFloat {
48 fn encode<W: IoWrite>(&self, writer: &mut W) -> Result<usize, <W as IoWrite>::Error> {
49 {
50 match self {
51 EncodeMinimizeFloat::F32(v) => v.encode(writer),
52 EncodeMinimizeFloat::F64(v) => {
53 let v = *v;
54 if is_exactly_representable(v) {
55 (v as f32).encode(writer)
56 } else {
57 v.encode(writer)
58 }
59 }
60 }
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 use rstest::rstest;
70
71 #[rstest]
72 #[case(123.456_f32,[Format::Float32.as_byte(), 0x42, 0xf6, 0xe9, 0x79])]
73 fn encode_float32<V: Encode, E: AsRef<[u8]> + Sized>(#[case] value: V, #[case] expected: E) {
74 let expected = expected.as_ref();
75
76 let mut buf = vec![];
77 let n = value.encode(&mut buf).unwrap();
78 assert_eq!(buf, expected);
79 assert_eq!(n, expected.len());
80 }
81
82 #[rstest]
83 #[case(123456.789_f64,[Format::Float64.as_byte(), 0x40, 0xfe, 0x24, 0x0c, 0x9f, 0xbe, 0x76, 0xc9])]
84 fn encode_float64<V: Encode, E: AsRef<[u8]> + Sized>(#[case] value: V, #[case] expected: E) {
85 let expected = expected.as_ref();
86
87 let mut buf = vec![];
88 let n = value.encode(&mut buf).unwrap();
89 assert_eq!(buf, expected);
90 assert_eq!(n, expected.len());
91 }
92
93 #[rstest]
94 #[case(1.0_f64, [Format::Float32.as_byte(), 0x3f, 0x80, 0x00, 0x00])]
95 #[case(1e39_f64, [Format::Float64.as_byte(), 0x48,0x07,0x82,0x87,0xf4,0x9c,0x4a,0x1d])]
96 fn encode_float_minimize<V: Into<EncodeMinimizeFloat>, E: AsRef<[u8]> + Sized>(
97 #[case] value: V,
98 #[case] expected: E,
99 ) {
100 let expected = expected.as_ref();
101 let encoder = value.into();
102
103 let mut buf = vec![];
104 let n = encoder.encode(&mut buf).unwrap();
105 assert_eq!(buf, expected);
106 assert_eq!(n, expected.len());
107 }
108}