1use core::{
2 mem::discriminant,
3 ffi::CStr
4};
5use alloc::{
6 vec::Vec,
7 string::String
8};
9
10pub(crate) fn pop_slice<'a>(input: &mut &'a [u8], len: usize) -> Option<&'a [u8]> {
14 input.take(..len)
15}
16
17pub(crate) fn take_be_u32(input: &mut &[u8]) -> Option<u32> {
21 Some(u32::from_be_bytes(pop_slice(input, 4)?.try_into().unwrap()))
22}
23
24pub(crate) fn take_be_u64(input: &mut &[u8]) -> Option<u64> {
28 Some(u64::from_be_bytes(pop_slice(input, 8)?.try_into().unwrap()))
29}
30
31pub(crate) fn read_first_be_u32(input: &[u8]) -> Option<u32> {
33 Some(u32::from_be_bytes(input.get(..4)?.try_into().unwrap()))
34}
35
36pub(crate) fn read_first_be_u64(input: &[u8]) -> Option<u64> {
38 Some(u64::from_be_bytes(input.get(..8)?.try_into().unwrap()))
39}
40
41pub(crate) fn take_utf8_until_nul_aligned<'a>(input: &mut &'a [u8], align: usize) -> Option<&'a str> {
42 let c_str = CStr::from_bytes_until_nul(input).unwrap();
43
44 let str = c_str.to_str().unwrap();
45
46 let len = c_str.to_bytes_with_nul().len();
47
48 if align != 0 {
49 pop_slice(input, len + (align - (len % align)) % align)?;
50 } else {
51 pop_slice(input, len)?;
52 }
53
54 Some(str)
55}
56
57pub(crate) fn take_utf8_until_nul<'a>(input: &mut &'a [u8]) -> Option<&'a str> {
58 let c_str = CStr::from_bytes_until_nul(input).unwrap();
59
60 let str = c_str.to_str().unwrap();
61
62 let len = c_str.to_bytes_with_nul().len();
63
64 pop_slice(input, len)?;
65
66 Some(str)
67}
68
69pub(crate) fn take_aligned<'a>(input: &mut &'a [u8], len: usize, align: usize) -> Option<&'a [u8]> {
70 pop_slice(input, len + (align - (len % align)) % align)?.get(..len)
71}
72
73pub(crate) fn variant_eq<T>(a: &T, b: &T) -> bool {
77 discriminant(a) == discriminant(b)
78}
79
80pub(crate) fn vec_strings_fmt(v: &Vec<String>) -> String {
82 let v_fmt: Vec<String> = v.iter().map(|i| format!("'{}'", i)).collect();
83
84 v_fmt.join(", ")
85}