1use rand::Rng;
2use serde::{Deserialize, Serialize};
3use std::ops::{Bound, RangeBounds};
4use type_uuid::Bytes;
5
6#[allow(dead_code)]
7pub fn vec_take<T, F: FnMut(&mut T) -> bool>(source: &mut Vec<T>, receiver: &mut Vec<T>, mut f: F) {
8 let mut i = 0;
9 while i < source.len() {
10 if f(&mut source[i]) {
11 let val = source.swap_remove(i);
12 receiver.push(val);
13 } else {
14 i += 1;
15 }
16 }
17}
18
19pub trait Align4 {
20 fn align4(self) -> Self;
21}
22
23impl Align4 for usize {
24 #[inline]
25 fn align4(mut self) -> Self {
26 if (self & 0x3) != 0 {
27 self = (self & !0x3) + 4;
28 }
29 self
30 }
31}
32
33impl Align4 for u32 {
34 #[inline]
35 fn align4(mut self) -> Self {
36 if (self & 0x3) != 0 {
37 self = (self & !0x3) + 4;
38 }
39 self
40 }
41}
42
43#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
44pub struct EndpointID(Bytes);
45
46impl EndpointID {
47 pub fn new() -> Self {
48 Self(uuid::Uuid::new_v4().into_bytes())
49 }
50}
51
52#[allow(dead_code)]
53pub fn rand_string(length: usize) -> String {
54 rand::thread_rng()
55 .sample_iter(&rand::distributions::Alphanumeric)
56 .take(length)
57 .map(char::from)
58 .collect()
59}
60
61pub fn range_to_offset_size<S: RangeBounds<usize>>(bounds: S) -> (usize, Option<usize>) {
62 let offset = match bounds.start_bound() {
63 Bound::Included(&bound) => bound,
64 Bound::Excluded(&bound) => bound + 1,
65 Bound::Unbounded => 0,
66 };
67 let size = match bounds.end_bound() {
68 Bound::Included(&bound) => Some(bound + 1 - offset),
69 Bound::Excluded(&bound) => Some(bound - offset),
70 Bound::Unbounded => None,
71 };
72
73 (offset, size)
74}