1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright © 2018–2019 Trevor Spiteri

// This library is free software: you can redistribute it and/or
// modify it under the terms of either
//
//   * the Apache License, Version 2.0 or
//   * the MIT License
//
// at your option.
//
// You should have recieved copies of the Apache License and the MIT
// License along with the library. If not, see
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.

use crate::{
    types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8},
    FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
    FixedU8,
};
use core::fmt::{Formatter, Result as FmtResult};
use serde::{
    de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor},
    ser::{Serialize, SerializeStruct, Serializer},
};

macro_rules! serde_fixed {
    ($Fixed:ident($LeEqU:ident) is $TBits:ident name $Name:expr) => {
        impl<Frac: $LeEqU> Serialize for $Fixed<Frac> {
            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
                let bits = self.to_bits();
                let mut state = serializer.serialize_struct($Name, 1)?;
                state.serialize_field("bits", &bits)?;
                state.end()
            }
        }

        impl<'de, Frac: $LeEqU> Deserialize<'de> for $Fixed<Frac> {
            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
                struct FixedVisitor;

                impl<'de> Visitor<'de> for FixedVisitor {
                    type Value = $TBits;

                    fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
                        formatter.write_str("struct ")?;
                        formatter.write_str($Name)
                    }

                    fn visit_seq<V: SeqAccess<'de>>(self, mut seq: V) -> Result<$TBits, V::Error> {
                        let bits = seq
                            .next_element()?
                            .ok_or_else(|| de::Error::invalid_length(0, &self))?;
                        Ok(bits)
                    }

                    fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<$TBits, V::Error> {
                        let mut bits = None;
                        while let Some(key) = map.next_key()? {
                            match key {
                                Field::Bits => {
                                    if bits.is_some() {
                                        return Err(de::Error::duplicate_field("bits"));
                                    }
                                    bits = Some(map.next_value()?);
                                }
                            }
                        }
                        let bits = bits.ok_or_else(|| de::Error::missing_field("bits"))?;
                        Ok(bits)
                    }
                }

                let bits = deserializer.deserialize_struct($Name, FIELDS, FixedVisitor)?;
                Ok($Fixed::from_bits(bits))
            }
        }
    };
}

serde_fixed! { FixedI8(LeEqU8) is i8 name "FixedI8" }
serde_fixed! { FixedI16(LeEqU16) is i16 name "FixedI16" }
serde_fixed! { FixedI32(LeEqU32) is i32 name "FixedI32" }
serde_fixed! { FixedI64(LeEqU64) is i64 name "FixedI64" }
serde_fixed! { FixedI128(LeEqU128) is i128 name "FixedI128" }
serde_fixed! { FixedU8(LeEqU8) is u8 name "FixedU8" }
serde_fixed! { FixedU16(LeEqU16) is u16 name "FixedU16" }
serde_fixed! { FixedU32(LeEqU32) is u32 name "FixedU32" }
serde_fixed! { FixedU64(LeEqU64) is u64 name "FixedU64" }
serde_fixed! { FixedU128(LeEqU128) is u128 name "FixedU128" }

const FIELDS: &[&str] = &["bits"];

enum Field {
    Bits,
}

impl<'de> Deserialize<'de> for Field {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Field, D::Error> {
        struct FieldVisitor;

        impl<'de> Visitor<'de> for FieldVisitor {
            type Value = Field;

            fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
                formatter.write_str("`bits`")
            }

            fn visit_str<E: de::Error>(self, value: &str) -> Result<Field, E> {
                match value {
                    "bits" => Ok(Field::Bits),
                    _ => Err(de::Error::unknown_field(value, FIELDS)),
                }
            }
        }

        deserializer.deserialize_identifier(FieldVisitor)
    }
}