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
120
use std::convert::TryInto;
use std::mem;
use std::mem::MaybeUninit;
use nalgebra::Point2;
#[derive(Debug, PartialEq)]
pub struct ComparisonNode(pub Point2<i8>, pub Point2<i8>);
impl From<[i8; 4]> for ComparisonNode {
fn from(data: [i8; 4]) -> Self {
let [y0, x0, y1, x1] = data;
Self(Point2::new(x0, y0), Point2::new(x1, y1))
}
}
impl From<[u8; 4]> for ComparisonNode {
fn from(data: [u8; 4]) -> Self {
let mut out: [MaybeUninit<i8>; 4] = unsafe {
mem::MaybeUninit::uninit().assume_init()
};
for (pos, o) in data.iter().zip(out.iter_mut()) {
*unsafe { o.assume_init_mut() } = i8::from_le_bytes(pos.to_le_bytes());
}
Self::from(
unsafe {
mem::transmute::<_, [i8; 4]>(out)
}
)
}
}
impl From<ComparisonNode> for [i8; 4] {
fn from(node: ComparisonNode) -> [i8; 4] {
[node.0.y, node.0.x, node.1.y, node.1.x]
}
}
impl From<ComparisonNode> for [u8; 4] {
fn from(node: ComparisonNode) -> [u8; 4] {
[
node.0.y.to_le_bytes()[0],
node.0.x.to_le_bytes()[0],
node.1.y.to_le_bytes()[0],
node.1.x.to_le_bytes()[0],
]
}
}
pub struct ThresholdNode {
pub idx: (usize, usize),
pub threshold: i16,
}
impl From<[u8; 10]> for ThresholdNode {
fn from(data: [u8; 10]) -> Self {
let idx0 = u32::from_be_bytes(data[0..4].try_into().unwrap()) as usize;
let idx1 = u32::from_be_bytes(data[4..8].try_into().unwrap()) as usize;
let threshold = i16::from_be_bytes(data[8..10].try_into().unwrap());
Self {
idx: (idx0, idx1),
threshold,
}
}
}
impl From<ThresholdNode> for [u8; 10] {
fn from(node: ThresholdNode) -> Self {
let idx0 = (node.idx.0 as u32).to_be_bytes();
let idx1 = (node.idx.1 as u32).to_be_bytes();
let threshold = node.threshold.to_be_bytes();
let vals =
idx0.iter()
.chain(idx1.iter())
.chain(threshold.iter());
let mut out: [MaybeUninit<u8>; 10] = unsafe {
mem::MaybeUninit::uninit().assume_init()
};
for (pos, o) in vals.zip(out.iter_mut()) {
*unsafe { o.assume_init_mut() } = *pos;
}
unsafe {
mem::transmute::<_, [u8; 10]>(out)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn comparison_node_convert_back_and_forth() {
let data: [i8; 4] = [-128, 42, -34, 127];
let buf: [u8; 4] = ComparisonNode::from(data.clone()).into();
let out: [i8; 4] = ComparisonNode::from(buf).into();
assert_eq!(data, out);
}
#[test]
fn threshold_node_convert_back_and_forth() {
let test_idx = (1, 2);
let test_threshold = 2;
let node = ThresholdNode {
idx: test_idx,
threshold: test_threshold,
};
let data: [u8; 10] = node.into();
let ThresholdNode { idx, threshold } = ThresholdNode::from(data);
assert_eq!(idx, test_idx);
assert_eq!(threshold, test_threshold);
}
}