Documentation
use crate::{
  endian::{read_uint32, uint16, uint32},
  error::{EmapiError, Result},
};

pub struct EmapiPayload;

impl EmapiPayload {
  pub fn uint8(value: u8) -> Vec<u8> {
    vec![value]
  }

  pub fn uint16(value: u16) -> Vec<u8> {
    uint16(value).to_vec()
  }

  pub fn uint32(value: u32) -> Vec<u8> {
    uint32(value).to_vec()
  }

  pub fn read_uint32(data: &[u8]) -> Result<u32> {
    if data.len() != 4 {
      return Err(EmapiError::Range {
        name: "data.length",
        min: 4,
        max: 4,
        value: data.len() as u64,
      });
    }
    read_uint32(data, 0)
  }

  pub fn file_chunk(index: u32, data: &[u8]) -> Result<Vec<u8>> {
    if index < 1 || index > u32::from(u16::MAX) {
      return Err(EmapiError::Range {
        name: "index",
        min: 1,
        max: u64::from(u16::MAX),
        value: u64::from(index),
      });
    }
    if data.len() > usize::from(u16::MAX) {
      return Err(EmapiError::Range {
        name: "data.length",
        min: 0,
        max: u64::from(u16::MAX),
        value: data.len() as u64,
      });
    }

    let mut payload = Vec::with_capacity(4 + data.len());
    payload.extend_from_slice(&uint16(index as u16));
    payload.extend_from_slice(&uint16(data.len() as u16));
    payload.extend_from_slice(data);
    Ok(payload)
  }
}