djin_protocol/types/
numerics.rs

1use crate::{hint, Parcel, Error, Settings};
2
3use std::io::prelude::*;
4
5use num_traits::{FromPrimitive, ToPrimitive};
6use byteorder::{ReadBytesExt, WriteBytesExt};
7
8/// An integer value that can be serialized and deserialized.
9pub trait Integer : Parcel + FromPrimitive + ToPrimitive { }
10
11impl Parcel for bool
12{
13    const TYPE_NAME: &'static str = "bool";
14
15    fn read_field(read: &mut dyn Read,
16                  _: &Settings,
17                  _: &mut hint::Hints) -> Result<Self, Error> {
18        if read.read_u8()? == 0 { Ok(false) } else { Ok(true) }
19    }
20
21    fn write_field(&self, write: &mut dyn Write,
22                   _: &Settings,
23                   _: &mut hint::Hints) -> Result<(), Error> {
24        write.write_u8(if *self { 1 } else { 0 })?;
25        Ok(())
26    }
27}
28
29impl Parcel for u8
30{
31    const TYPE_NAME: &'static str = "u8";
32
33    fn read_field(read: &mut dyn Read,
34                  _: &Settings,
35                  _: &mut hint::Hints) -> Result<Self, Error> { Ok(read.read_u8()?) }
36    fn write_field(&self, write: &mut dyn Write,
37                   _: &Settings,
38                   _: &mut hint::Hints)
39        -> Result<(), Error> { write.write_u8(*self)?; Ok(()) }
40}
41
42impl Parcel for i8
43{
44    const TYPE_NAME: &'static str = "i8";
45
46    fn read_field(read: &mut dyn Read,
47                  _: &Settings,
48                  _: &mut hint::Hints) -> Result<Self, Error> { Ok(read.read_i8()?) }
49    fn write_field(&self, write: &mut dyn Write,
50                   _: &Settings,
51                   _: &mut hint::Hints)
52        -> Result<(), Error> { write.write_i8(*self)?; Ok(()) }
53}
54
55macro_rules! impl_parcel_for_numeric {
56    ($ty:ident => [$read_fn:ident : $write_fn:ident]) => {
57        impl Parcel for $ty {
58            const TYPE_NAME: &'static str = stringify!($ty);
59
60            fn read_field(read: &mut dyn Read,
61                          settings: &Settings,
62                          _: &mut hint::Hints) -> Result<Self, Error> {
63                Ok(settings.byte_order.$read_fn(read)?)
64            }
65
66            fn write_field(&self, write: &mut dyn Write,
67                           settings: &Settings,
68                           _: &mut hint::Hints) -> Result<(), Error> {
69                settings.byte_order.$write_fn(*self, write)?; Ok(())
70            }
71        }
72    };
73}
74
75impl_parcel_for_numeric!(u16 => [read_u16 : write_u16]);
76impl_parcel_for_numeric!(i16 => [read_i16 : write_i16]);
77impl_parcel_for_numeric!(u32 => [read_u32 : write_u32]);
78impl_parcel_for_numeric!(i32 => [read_i32 : write_i32]);
79impl_parcel_for_numeric!(u64 => [read_u64 : write_u64]);
80impl_parcel_for_numeric!(i64 => [read_i64 : write_i64]);
81impl_parcel_for_numeric!(f32 => [read_f32 : write_f32]);
82impl_parcel_for_numeric!(f64 => [read_f64 : write_f64]);
83
84impl Integer for u8 { }
85impl Integer for i8 { }
86impl Integer for u16 { }
87impl Integer for i16 { }
88impl Integer for u32 { }
89impl Integer for i32 { }
90impl Integer for u64 { }
91impl Integer for i64 { }
92