summaryrefslogtreecommitdiff
path: root/whrd/src/parse.rs
blob: 83542d8eed56eb2db9842feb066c8ded8a1466e0 (plain)
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
use std::io::Read;

use crate::error::{EncodeDecodeError, WhereError, WhereResult};
use crate::PayloadCursor;

pub fn read_field<const N: usize, F, T>(cursor: &mut PayloadCursor, convert_func: F) -> WhereResult<T>
where
    F: Fn([u8; N]) -> WhereResult<T>
{
    let mut buffer = [0u8; N];
    cursor.read_exact(&mut buffer)?;

    let value = convert_func(buffer)?;
    Ok(value)
}

pub fn read_field_dynamic<F, T>(cursor: &mut PayloadCursor, size: usize, convert_func: F) -> WhereResult<T>
where
    F: Fn(Vec<u8>) -> WhereResult<T>
{
    let mut buffer = vec![0u8; size];
    cursor.read_exact(&mut buffer)?;

    let value = convert_func(buffer)?;
    Ok(value)
}

pub fn read_bool_field(cursor: &mut PayloadCursor) -> WhereResult<bool> {
    let value = read_field::<1, _, _>(cursor, |buf| Ok(buf[0] == 1))?;
    Ok(value)
}

pub fn read_string_field(cursor: &mut PayloadCursor, max_length: u32) -> WhereResult<String> {
    let string_length = read_field(cursor, |buf| Ok(u32::from_be_bytes(buf)))?;

    if string_length > max_length {
        return Err(WhereError::EncodeDecodeError(EncodeDecodeError::StringSizeLimitExceeded(string_length, max_length as usize)));
    }

    let string = read_field_dynamic(cursor, string_length as usize, |buf| Ok(String::from_utf8(buf)?))?;

    Ok(string)
}