pretty-good 0.2.2

RFC4880 (OpenPGP Message Format) library
Documentation
use std::time::Duration;

use byteorder::{BigEndian, ReadBytesExt};
use nom::{ErrorKind, IResult, be_u16};
use nom::Err as NomErr;
use num::BigUint;

use types::*;

pub(crate) fn parse_time_subpacket<T>(mut inp: &[u8]) -> Result<Duration, NomErr<T>> {
    inp.read_u32::<BigEndian>()
        .map(|seconds| Duration::from_secs(u64::from(seconds)))
        .map_err(|_| NomErr::Code(ErrorKind::Custom(NomError::IntegerReadError as u32)))
}

named!(
    pub pgp_time<Duration>,
    map_res!(take!(4), parse_time_subpacket::<&[u8]>)
);

pub(crate) fn pgp_mpi(inp: &[u8]) -> IResult<&[u8], BigUint> {
    let (remaining, length_bits) = match be_u16(inp) {
        IResult::Done(remaining, length_bits) => (remaining, length_bits),
        IResult::Error(e) => return IResult::Error(e),
        IResult::Incomplete(i) => return IResult::Incomplete(i),
    };

    let length_bytes = (length_bits + 7) / 8;

    let (remaining, mpi_slice) = match take!(remaining, length_bytes) {
        IResult::Done(remaining, mpi_slice) => (remaining, mpi_slice),
        IResult::Error(e) => return IResult::Error(e),
        IResult::Incomplete(i) => return IResult::Incomplete(i),
    };

    IResult::Done(remaining, BigUint::from_bytes_be(mpi_slice))
}