sqlx_mysql/types/
float.rs1use byteorder::{ByteOrder, LittleEndian};
2
3use crate::decode::Decode;
4use crate::encode::{Encode, IsNull};
5use crate::error::BoxDynError;
6use crate::protocol::text::ColumnType;
7use crate::types::Type;
8use crate::{MySql, MySqlTypeInfo, MySqlValueFormat, MySqlValueRef};
9
10fn real_compatible(ty: &MySqlTypeInfo) -> bool {
11 matches!(ty.r#type, ColumnType::Float | ColumnType::Double)
13}
14
15impl Type<MySql> for f32 {
16 fn type_info() -> MySqlTypeInfo {
17 MySqlTypeInfo::binary(ColumnType::Float)
18 }
19
20 fn compatible(ty: &MySqlTypeInfo) -> bool {
21 real_compatible(ty)
22 }
23}
24
25impl Type<MySql> for f64 {
26 fn type_info() -> MySqlTypeInfo {
27 MySqlTypeInfo::binary(ColumnType::Double)
28 }
29
30 fn compatible(ty: &MySqlTypeInfo) -> bool {
31 real_compatible(ty)
32 }
33}
34
35impl Encode<'_, MySql> for f32 {
36 fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
37 buf.extend(&self.to_le_bytes());
38
39 Ok(IsNull::No)
40 }
41}
42
43impl Encode<'_, MySql> for f64 {
44 fn encode_by_ref(&self, buf: &mut Vec<u8>) -> Result<IsNull, BoxDynError> {
45 buf.extend(&self.to_le_bytes());
46
47 Ok(IsNull::No)
48 }
49}
50
51impl Decode<'_, MySql> for f32 {
52 fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
53 Ok(match value.format() {
54 MySqlValueFormat::Binary => {
55 let buf = value.as_bytes()?;
56
57 match buf.len() {
58 4 => LittleEndian::read_f32(buf),
60 #[allow(clippy::cast_possible_truncation)]
63 8 => LittleEndian::read_f64(buf) as f32,
64 other => {
65 return Err(format!(
68 "expected a FLOAT as 4 or 8 bytes, got {other} bytes; \
69 note that decoding DECIMAL as `f32` is not supported \
70 due to differing semantics"
71 )
72 .into());
73 }
74 }
75 }
76
77 MySqlValueFormat::Text => value.as_str()?.parse()?,
78 })
79 }
80}
81
82impl Decode<'_, MySql> for f64 {
83 fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
84 Ok(match value.format() {
85 MySqlValueFormat::Binary => {
86 let buf = value.as_bytes()?;
87
88 match buf.len() {
90 4 => LittleEndian::read_f32(buf) as f64,
92 8 => LittleEndian::read_f64(buf),
93 other => {
94 return Err(format!(
97 "expected a DOUBLE as 4 or 8 bytes, got {other} bytes; \
98 note that decoding DECIMAL as `f64` is not supported \
99 due to differing semantics"
100 )
101 .into());
102 }
103 }
104 }
105 MySqlValueFormat::Text => value.as_str()?.parse()?,
106 })
107 }
108}