nrbf 0.2.2

A parser for the .NET Remoting Binary Format (NRBF).
Documentation
use std::num::NonZeroU32;

use nom::{IResult, ToUsize};

use crate::{
  data_type::Int32,
  error::{Error, error_position},
};

pub fn into_failure<E>(err: nom::Err<E>) -> nom::Err<E> {
  match err {
    nom::Err::Error(e) => nom::Err::Failure(e),
    err => err,
  }
}

pub fn library_id(input: &[u8]) -> IResult<&[u8], NonZeroU32, Error<'_>> {
  let err_input = input;

  match Int32::parse(input) {
    Ok((input, object_id)) => {
      if let Some(object_id) = u32::try_from(i32::from(object_id)).ok().and_then(NonZeroU32::new) {
        Ok((input, object_id))
      } else {
        Err(nom::Err::Failure(error_position!(err_input, InvalidLibraryId)))
      }
    },
    Err(err) => Err(err),
  }
}

pub fn object_id(input: &[u8]) -> IResult<&[u8], NonZeroU32, Error<'_>> {
  let err_input = input;

  match Int32::parse(input) {
    Ok((input, object_id)) => {
      if let Some(object_id) = u32::try_from(i32::from(object_id)).ok().and_then(NonZeroU32::new) {
        Ok((input, object_id))
      } else {
        Err(nom::Err::Failure(error_position!(err_input, InvalidObjectId)))
      }
    },
    Err(err) => Err(err),
  }
}

pub fn length(input: &[u8]) -> IResult<&[u8], usize, Error<'_>> {
  let err_input = input;

  match Int32::parse(input) {
    Ok((input, length)) => {
      if let Ok(length) = u32::try_from(i32::from(length)) {
        Ok((input, length.to_usize()))
      } else {
        Err(nom::Err::Failure(error_position!(err_input, InvalidLength)))
      }
    },
    Err(err) => Err(err),
  }
}