eml_codec/text/
boundary.rs1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 combinator::{eof, opt},
5 sequence::tuple,
6 IResult,
7};
8
9use crate::text::whitespace::obs_crlf;
10
11#[derive(Debug, PartialEq)]
12pub enum Delimiter {
13 Next,
14 Last,
15}
16
17pub fn boundary<'a>(boundary: &[u8]) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Delimiter> + '_ {
18 move |input: &[u8]| {
19 let (rest, (_, _, _, last, _)) = tuple((
20 opt(obs_crlf),
21 tag(b"--"),
22 tag(boundary),
23 opt(tag(b"--")),
24 alt((obs_crlf, eof)),
25 ))(input)?;
26 match last {
27 Some(_) => Ok((rest, Delimiter::Last)),
28 None => Ok((rest, Delimiter::Next)),
29 }
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn test_boundary_next() {
39 assert_eq!(
40 boundary(b"hello")(b"\r\n--hello\r\n"),
41 Ok((&b""[..], Delimiter::Next))
42 );
43 }
44
45 #[test]
46 fn test_boundary_last() {
47 assert_eq!(
48 boundary(b"hello")(b"\r\n--hello--\r\n"),
49 Ok((&b""[..], Delimiter::Last))
50 );
51 }
52}