sunlight/utils/
nom_helper.rs

1use nom::{
2    bytes::complete::take,
3    number::complete::{le_i32, le_i64, le_u8, le_u32, le_u64},
4};
5use std::mem::size_of;
6
7pub(crate) enum Endian {
8    /**Little Endian */
9    Le,
10}
11
12/**
13 * Nom four (4) bytes to u32
14 * Need to specify Endianess
15 */
16pub(crate) fn nom_unsigned_four_bytes(data: &[u8], endian: Endian) -> nom::IResult<&[u8], u32> {
17    let (input, value_data) = take(size_of::<u32>())(data)?;
18
19    let (_, value) = match endian {
20        Endian::Le => le_u32(value_data)?,
21    };
22
23    Ok((input, value))
24}
25
26/**
27 * Nom eight (8) bytes to u64
28 * Need to specify Endianess
29 */
30pub(crate) fn nom_unsigned_eight_bytes(data: &[u8], endian: Endian) -> nom::IResult<&[u8], u64> {
31    let (input, value_data) = take(size_of::<u64>())(data)?;
32
33    let (_, value) = match endian {
34        Endian::Le => le_u64(value_data)?,
35    };
36    Ok((input, value))
37}
38
39/**
40 * Nom one (1) bytes to u8
41 * Need to specify Endianess
42 */
43pub(crate) fn nom_unsigned_one_byte(data: &[u8], endian: Endian) -> nom::IResult<&[u8], u8> {
44    let (input, value_data) = take(size_of::<u8>())(data)?;
45
46    let (_, value) = match endian {
47        Endian::Le => le_u8(value_data)?,
48    };
49    Ok((input, value))
50}
51
52/**
53 * Nom four (4) bytes to i32
54 * Need to specify Endianess
55 */
56pub(crate) fn nom_signed_four_bytes(data: &[u8], endian: Endian) -> nom::IResult<&[u8], i32> {
57    let (input, value_data) = take(size_of::<u32>())(data)?;
58
59    let (_, value) = match endian {
60        Endian::Le => le_i32(value_data)?,
61    };
62
63    Ok((input, value))
64}
65
66/**
67 * Nom eight (8) bytes to i64
68 * Need to specify Endianess
69 */
70pub(crate) fn nom_signed_eight_bytes(data: &[u8], endian: Endian) -> nom::IResult<&[u8], i64> {
71    let (input, value_data) = take(size_of::<u64>())(data)?;
72
73    let (_, value) = match endian {
74        Endian::Le => le_i64(value_data)?,
75    };
76    Ok((input, value))
77}
78
79#[cfg(test)]
80mod tests {
81    use crate::utils::nom_helper::{
82        Endian, nom_signed_eight_bytes, nom_signed_four_bytes, nom_unsigned_eight_bytes,
83        nom_unsigned_four_bytes, nom_unsigned_one_byte,
84    };
85
86    #[test]
87    fn test_nom_signed_eight_bytes() {
88        let test = [2, 0, 0, 0, 0, 0, 0, 0];
89        let (_, results) = nom_signed_eight_bytes(&test, Endian::Le).unwrap();
90        assert_eq!(results, 2);
91    }
92
93    #[test]
94    fn test_nom_signed_four_bytes() {
95        let test = [2, 0, 0, 0];
96        let (_, results) = nom_signed_four_bytes(&test, Endian::Le).unwrap();
97        assert_eq!(results, 2);
98    }
99
100    #[test]
101    fn test_nom_unsigned_four_bytes() {
102        let test = [0, 0, 0, 2];
103        let (_, results) = nom_unsigned_four_bytes(&test, Endian::Le).unwrap();
104        assert_eq!(results, 33554432);
105    }
106
107    #[test]
108    fn test_nom_unsigned_eight_bytes() {
109        let test = [0, 0, 0, 0, 0, 0, 0, 2];
110        let (_, results) = nom_unsigned_eight_bytes(&test, Endian::Le).unwrap();
111        assert_eq!(results, 144115188075855872);
112    }
113
114    #[test]
115    fn test_nom_unsigned_one_byte() {
116        let test = [2];
117        let (_, results) = nom_unsigned_one_byte(&test, Endian::Le).unwrap();
118        assert_eq!(results, 2);
119    }
120}