rekt_common/libs/
utils.rs

1use std::collections::HashSet;
2use std::mem::size_of;
3
4use crate::libs::types::TopicId;
5
6/**===================================*
7*                                     *
8*     Array/vec/set manipulators      *
9*                                     *
10*=====================================*/
11
12/**
13 * This functions return a bytes slice according to
14 * the given bounds. FROM and TO are include in the returned slice.
15 *
16 * @param buffer: &[u8], the original array,
17 * @param from: usize, first bound,
18 * @param to: usize, last bound,
19 *
20 * @return Vec<u8>, the slice requested
21 */
22pub fn get_bytes_from_slice(
23    buffer: &[u8],
24    from: usize,
25    to: usize,
26) -> Vec<u8> {
27    // 1 - check bound validity
28    match () {
29        _ if to < from => panic!("from is greater than to"),
30        _ if to >= buffer.len() => panic!("to is greater than the last index"),
31        _ => (),
32    }
33
34    // 2 - return the correct slice
35    buffer[from..to + 1].into()
36}
37
38
39/**
40 * This method is an helper to find an u64 at position
41 * in a buffer of u8
42 *
43 * @param buffer: &[u8], the source of the u64
44 * @param position: usize, the position of the first byte of the u64
45 *
46 * @return u64
47 */
48pub fn get_u64_at_pos(buffer: &[u8], position: usize) -> Result<u64, &str>
49{
50    let slice = get_bytes_from_slice(buffer, position, position + size_of::<u64>() - 1);
51    if slice.len() != 8 {
52        return Err("Slice len is invalid to convert it into an u64.");
53    }
54    Ok(u64::from_le_bytes(slice.try_into().unwrap()))
55}
56
57/**
58 * This method is an helper to find an u32 at position
59 * in a buffer of u8
60 *
61 * @param buffer: &[u8], the source of the u32
62 * @param position: usize, the position of the first byte of the u32
63 *
64 * @return u32
65 */
66pub fn get_u32_at_pos(buffer: &[u8], position: usize) -> Result<u32, &str>
67{
68    let slice = get_bytes_from_slice(buffer, position, position + size_of::<u32>() - 1);
69    if slice.len() != 4 {
70        return Err("Slice len is invalid to convert it into an u32.");
71    }
72    Ok(u32::from_le_bytes(slice.try_into().unwrap()))
73}
74
75/**
76 * This method is an helper to find an u16 at position
77 * in a buffer of u8
78 *
79 * @param buffer: &[u8], the source of the u16
80 * @param position: usize, the position of the first byte of the u16
81 *
82 * @return u16
83 */
84pub fn get_u16_at_pos(buffer: &[u8], position: usize) -> Result<u16, &str>
85{
86    let slice = get_bytes_from_slice(buffer, position, position + size_of::<u16>() - 1);
87    if slice.len() != 2 {
88        return Err("Slice len is invalid to convert it into an u16.");
89    }
90    Ok(u16::from_le_bytes(slice.try_into().unwrap()))
91}
92
93
94/**
95 * This method return a tuple off two vec containing
96 * added and removed values.
97 *
98 * @param new_set: &HashSet<TopicId>, The new set containing incoming values
99 * @param current_set: &HashSet<TopicId>, the current set containing actual values
100 *
101 * @return added_values, removed_values: (Vec<TopicId>, Vec<TopicId>): two vectors containing differences from the original set
102 */
103pub fn diff_hashsets(new_set: &HashSet<TopicId>, current_set: &HashSet<TopicId>) -> (Vec<TopicId>, Vec<TopicId>) {
104    let added_values = new_set.difference(current_set).cloned().collect();
105    let removed_values = current_set.difference(new_set).cloned().collect();
106    (added_values, removed_values)
107}
108
109/**
110 * This method return the u8 image of the
111 * given bitfields. The bitfield must be in little endian
112 *
113 * @param bitfields: Vec<u8>
114 *
115 * @return u8
116 */
117pub fn vec_to_u8(bitfield: Vec<u8>) -> u8 {
118    if bitfield.len() != 8 {
119        return panic!("Bitfield length is invalid ! It must be exactly 8.");
120    }
121    (bitfield[0] << 7) | (bitfield[1] << 6) | (bitfield[2] << 5) | (bitfield[3] << 4) | (bitfield[4] << 3) | (bitfield[5] << 2) | (bitfield[6] << 1) | (bitfield[7] << 0)
122}
123
124/**
125 * This method return the bitfield image of the
126 * given u8.
127 *
128 * @param number: u8
129 *
130 * @return Vec<u8>, bitfield in big endian
131 */
132pub fn u8_to_vec_be(number: u8) -> Vec<u8> {
133    let mut bits = Vec::with_capacity(8);
134    for i in 0..8 {
135        bits.push(if (number & (1 << i)) != 0 { 1 } else { 0 });
136    }
137    bits.reverse();
138    bits
139}