use postcard::{from_bytes, to_allocvec};
use reifydb_value::value::{Value, ordered_f32::OrderedF32, ordered_f64::OrderedF64};
use serde::{
Deserialize,
de::{
IntoDeserializer,
value::{Error as DeError, F32Deserializer, F64Deserializer},
},
};
#[test]
fn an_ordered_f64_rejects_a_nan_that_arrives_as_an_f32() {
let deserializer: F32Deserializer<DeError> = f32::NAN.into_deserializer();
let result = OrderedF64::deserialize(deserializer);
assert!(result.is_err(), "an f32 NaN must not deserialize into OrderedF64: {result:?}");
}
#[test]
fn an_ordered_f32_rejects_a_nan_that_arrives_as_an_f64() {
let deserializer: F64Deserializer<DeError> = f64::NAN.into_deserializer();
let result = OrderedF32::deserialize(deserializer);
assert!(result.is_err(), "an f64 NaN must not deserialize into OrderedF32: {result:?}");
}
#[test]
fn the_nan_deserialize_error_names_the_ordered_float_type() {
let f64_deserializer: F64Deserializer<DeError> = f64::NAN.into_deserializer();
let f32_deserializer: F32Deserializer<DeError> = f32::NAN.into_deserializer();
let f64_error = OrderedF64::deserialize(f64_deserializer).unwrap_err().to_string();
let f32_error = OrderedF32::deserialize(f32_deserializer).unwrap_err().to_string();
assert!(f64_error.contains("OrderedF64"), "f64 error must name the type: {f64_error}");
assert!(f32_error.contains("OrderedF32"), "f32 error must name the type: {f32_error}");
}
#[test]
fn a_deserialized_negative_zero_equals_a_constructed_one() {
let f64_decoded = from_bytes::<OrderedF64>(&to_allocvec(&-0.0f64).unwrap()).unwrap();
let f32_decoded = from_bytes::<OrderedF32>(&to_allocvec(&-0.0f32).unwrap()).unwrap();
assert_eq!(f64_decoded, OrderedF64::try_from(-0.0f64).unwrap());
assert_eq!(f32_decoded, OrderedF32::try_from(-0.0f32).unwrap());
}
#[test]
fn a_postcard_value_carrying_nan_float_bits_fails_to_decode() {
let mut float8_bytes = to_allocvec(&Value::Float8(OrderedF64::try_from(1.0f64).unwrap())).unwrap();
let float8_len = float8_bytes.len();
float8_bytes[float8_len - 8..].copy_from_slice(&f64::NAN.to_le_bytes());
let mut float4_bytes = to_allocvec(&Value::Float4(OrderedF32::try_from(1.0f32).unwrap())).unwrap();
let float4_len = float4_bytes.len();
float4_bytes[float4_len - 4..].copy_from_slice(&f32::NAN.to_le_bytes());
let float8_result = from_bytes::<Value>(&float8_bytes);
let float4_result = from_bytes::<Value>(&float4_bytes);
assert!(float8_result.is_err(), "NaN bits must not decode into Value::Float8: {float8_result:?}");
assert!(float4_result.is_err(), "NaN bits must not decode into Value::Float4: {float4_result:?}");
}