tof_dataclasses/
version.rs

1#[cfg(feature="random")]
2use crate::FromRandom;
3
4#[cfg(feature="random")]
5use rand::Rng;
6
7use std::fmt;
8
9#[cfg(feature = "pybindings")]
10use pyo3::pyclass;
11
12/// The Protocol version is designed in such 
13/// a way that we can "hijack" an existing 
14/// field, using the most significant digits.
15///
16/// It uses the 2 most significant bit of an u8,
17/// so it should be possible to basically slap 
18/// this on to anyting
19#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
20#[repr(u8)]
21#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
22pub enum ProtocolVersion {
23  Unknown  = 0u8,
24  V1       = 64u8,
25  V2       = 128u8,
26  V3       = 192u8,
27}
28
29impl fmt::Display for ProtocolVersion {
30  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31    let r = serde_json::to_string(self).unwrap_or(
32      String::from("Error: Unknown/Incompatible verison"));
33    write!(f, "<ProtocolVersion: {}>", r)
34  }
35}
36
37impl ProtocolVersion {
38  pub fn to_u8(&self) -> u8 {
39    match self {
40      ProtocolVersion::Unknown => {
41        return 0;
42      }
43      ProtocolVersion::V1 => {
44        return 64;
45      }
46      ProtocolVersion::V2 => {
47        return 128;
48      }
49      ProtocolVersion::V3 => {
50        return 192;
51      }
52    }
53  }
54}
55
56impl From<u8> for ProtocolVersion {
57  fn from(value: u8) -> Self {
58    match value {
59        0 => ProtocolVersion::Unknown,
60       64 => ProtocolVersion::V1,
61      128 => ProtocolVersion::V2,
62      192 => ProtocolVersion::V3,
63      _   => ProtocolVersion::Unknown
64    }
65  }
66}
67
68#[cfg(feature = "random")]
69impl FromRandom for ProtocolVersion {
70  
71  fn from_random() -> Self {
72    let choices = [
73      ProtocolVersion::Unknown,
74      ProtocolVersion::V1,
75      ProtocolVersion::V2,
76      ProtocolVersion::V3,
77    ];
78    let mut rng  = rand::thread_rng();
79    let idx = rng.gen_range(0..choices.len());
80    choices[idx]
81  }
82}
83
84#[test]
85#[cfg(feature = "random")]
86fn test_protocol_version() {
87  for _ in 0..100 {
88    let pv    = ProtocolVersion::from_random();
89    let pv_u8 = pv.to_u8();
90    let u8_pv = ProtocolVersion::from(pv_u8);
91    assert_eq!(pv, u8_pv);
92  }
93}
94