Add support for interpreting f32 in float.{from-bytes, to-bytes} (#5480)

This commit is contained in:
+merlan #flirora 2024-11-27 06:04:54 -05:00 committed by GitHub
parent e550dce62d
commit 6bf1350b16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 16 deletions

View File

@ -128,16 +128,21 @@ impl f64 {
#[default(Endianness::Little)] #[default(Endianness::Little)]
endian: Endianness, endian: Endianness,
) -> StrResult<f64> { ) -> StrResult<f64> {
// Convert slice to an array of length 8. // Convert slice to an array of length 4 or 8.
let buf: [u8; 8] = match bytes.as_ref().try_into() { if let Ok(buffer) = <[u8; 8]>::try_from(bytes.as_ref()) {
Ok(buffer) => buffer, return Ok(match endian {
Err(_) => bail!("bytes must have a length of exactly 8"), Endianness::Little => f64::from_le_bytes(buffer),
Endianness::Big => f64::from_be_bytes(buffer),
});
};
if let Ok(buffer) = <[u8; 4]>::try_from(bytes.as_ref()) {
return Ok(match endian {
Endianness::Little => f32::from_le_bytes(buffer),
Endianness::Big => f32::from_be_bytes(buffer),
} as f64);
}; };
Ok(match endian { bail!("bytes must have a length of 4 or 8");
Endianness::Little => f64::from_le_bytes(buf),
Endianness::Big => f64::from_be_bytes(buf),
})
} }
/// Converts a float to bytes. /// Converts a float to bytes.
@ -153,13 +158,25 @@ impl f64 {
#[named] #[named]
#[default(Endianness::Little)] #[default(Endianness::Little)]
endian: Endianness, endian: Endianness,
) -> Bytes { #[named]
match endian { #[default(8)]
size: u32,
) -> StrResult<Bytes> {
Ok(match size {
8 => match endian {
Endianness::Little => self.to_le_bytes(), Endianness::Little => self.to_le_bytes(),
Endianness::Big => self.to_be_bytes(), Endianness::Big => self.to_be_bytes(),
} }
.as_slice() .as_slice()
.into() .into(),
4 => match endian {
Endianness::Little => (self as f32).to_le_bytes(),
Endianness::Big => (self as f32).to_be_bytes(),
}
.as_slice()
.into(),
_ => bail!("size must be either 4 or 8"),
})
} }
} }

View File

@ -53,8 +53,13 @@
#test(1.0.to-bytes(), bytes((0, 0, 0, 0, 0, 0, 240, 63))) #test(1.0.to-bytes(), bytes((0, 0, 0, 0, 0, 0, 240, 63)))
#test(1.0.to-bytes(endian: "big"), bytes((63, 240, 0, 0, 0, 0, 0, 0))) #test(1.0.to-bytes(endian: "big"), bytes((63, 240, 0, 0, 0, 0, 0, 0)))
#test(float.from-bytes(bytes((0, 0, 32, 64))), 2.5)
#test(float.from-bytes(bytes((64, 32, 0, 0)), endian: "big"), 2.5)
#test(2.5.to-bytes(size: 4), bytes((0, 0, 32, 64)))
#test(2.5.to-bytes(size: 4, endian: "big"), bytes((64, 32, 0, 0)))
--- float-from-bytes-bad-length --- --- float-from-bytes-bad-length ---
// Error: 2-54 bytes must have a length of exactly 8 // Error: 2-54 bytes must have a length of 4 or 8
#float.from-bytes(bytes((0, 0, 0, 0, 0, 0, 0, 1, 0))) #float.from-bytes(bytes((0, 0, 0, 0, 0, 0, 0, 1, 0)))
--- float-repr --- --- float-repr ---