1use crate::{Error, Shape, Wire, schema::Schema};
2use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
3
4macro_rules! finite {
5 ($name:ident, $primitive:ty, $bits:literal) => {
6 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
11 pub struct $name($primitive);
12 impl $name {
13 pub fn new(value: $primitive) -> Result<Self, Error> {
15 if value.is_finite() {
16 Ok(Self(value))
17 } else {
18 Err(Error::Malformed)
19 }
20 }
21 pub fn get(self) -> $primitive {
23 self.0
24 }
25 }
26 impl Serialize for $name {
27 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
28 self.0.serialize(serializer)
29 }
30 }
31 impl<'de> Deserialize<'de> for $name {
32 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
33 Self::new(<$primitive>::deserialize(deserializer)?)
34 .map_err(|_| de::Error::custom("non-finite float"))
35 }
36 }
37 impl Wire for $name {
38 const SHAPE: Shape = Shape::scalar($bits / 8);
39 const SCHEMA: Schema = Schema::Float($bits);
40 }
41 };
42}
43finite!(FiniteF32, f32, 32);
44finite!(FiniteF64, f64, 64);