segment parser is working

This commit is contained in:
Quentin 2023-06-19 18:18:15 +02:00
parent 25bc3bb55c
commit ddf6311925
Signed by: quentin
GPG key ID: E9602264D639FF68
4 changed files with 62 additions and 0 deletions

6
src/error.rs Normal file
View file

@ -0,0 +1,6 @@
use nom;
#[derive(Debug, PartialEq)]
pub enum IMFError<'a> {
Segment(nom::Err<nom::error::Error<&'a [u8]>>),
}

View file

@ -1,2 +1,3 @@
pub mod error;
pub mod fragments;
pub mod multipass;

View file

@ -0,0 +1 @@
pub mod segment;

View file

@ -1,7 +1,61 @@
use std::convert::TryFrom;
use nom::{
IResult,
branch::alt,
bytes::complete::{is_not, tag},
combinator::recognize,
sequence::{pair, terminated},
multi::many0,
};
use crate::error::IMFError;
#[derive(Debug, PartialEq)]
pub struct Segment<'a> {
pub header: &'a [u8],
pub body: &'a [u8],
}
const cr: u8 = 0x0D;
const lf: u8 = 0x0A;
const crlf: &[u8] = &[cr, lf];
impl<'a> TryFrom<&'a [u8]> for Segment<'a> {
type Error = IMFError<'a>;
fn try_from(buffer: &'a [u8]) -> Result<Self, Self::Error> {
terminated(
recognize(many0(line)),
obs_crlf
)(buffer)
.map_err(|e| IMFError::Segment(e))
.map(|(body, header)| Segment { header, body })
}
}
fn line(input: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
pair(
is_not(crlf),
obs_crlf,
)(input)
}
fn obs_crlf(input: &[u8]) -> IResult<&[u8], &[u8]> {
alt((tag(crlf), tag(&[cr]), tag(&[lf])))(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_segment() {
assert_eq!(
Segment::try_from(&b"From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n\r\nHello world!"[..]),
Ok(Segment {
body: b"Hello world!",
header: b"From: hello@world.com\r\nDate: 12 Mar 1997 07:33:25 Z\r\n",
})
);
}
}