Showing the changes to git-object/src/commit (1 of 3 files). Show all
Unified · Split
| @@ -6,43 +6,54 @@ use crate::{ · 5 unmodified lines | ||
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | 8 | mod decode { |
| 9 | + use nom::{ | |
| 10 | + branch::alt, | |
| 11 | + bytes::complete::{tag, take_till1}, | |
| 12 | + combinator::all_consuming, | |
| 13 | + error::ParseError, | |
| 14 | + sequence::pair, | |
| 15 | + IResult, | |
| 16 | + }; | |
| 17 | + | |
| 9 | 18 | use crate::bstr::{BStr, ByteSlice}; |
| 10 | − use nom::branch::alt; | |
| 11 | − use nom::bytes::complete::{tag, take_till1}; | |
| 12 | − use nom::combinator::all_consuming; | |
| 13 | − use nom::error::ParseError; | |
| 14 | − use nom::sequence::pair; | |
| 15 | − use nom::IResult; | |
| 16 | − use std::convert::TryInto; | |
| 17 | 19 | |
| 18 | 20 | fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> { |
| 19 | 21 | alt((tag(b"\r\n"), tag(b"\n")))(i) |
| 20 | 22 | } |
| 21 | 23 | |
| 22 | − pub fn nomfoo<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&'a BStr, Option<&'a BStr>), E> { | |
| 24 | + fn subject_and_body<'a, E: ParseError<&'a [u8]>>( | |
| 25 | + i: &'a [u8], | |
| 26 | + ) -> IResult<&'a [u8], (&'a BStr, Option<&'a BStr>), E> { | |
| 23 | 27 | let mut c = i; |
| 28 | + let mut consumed_bytes = 0; | |
| 24 | 29 | while !c.is_empty() { |
| 25 | 30 | c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) { |
| 26 | − Ok((i1, segment)) => match pair::<_, _, _, E, _, _>(newline, newline)(i1) { | |
| 27 | − Ok((body, _)) => { | |
| 28 | − // SAFETY: the pointers are pointing to the same slice. | |
| 29 | − #[allow(unsafe_code)] | |
| 30 | − let consumed_bytes = unsafe { segment.as_ptr_range().end.offset_from(i.as_ptr()) }; | |
| 31 | − return Ok(( | |
| 32 | − &[], | |
| 33 | − ( | |
| 34 | − &i[0usize..consumed_bytes.try_into().expect("positive offset")].as_bstr(), | |
| 35 | − (!body.is_empty()).then(|| body.as_bstr()), | |
| 36 | − ), | |
| 37 | − )); | |
| 31 | + Ok((i1, segment)) => { | |
| 32 | + consumed_bytes += segment.len(); | |
| 33 | + match pair::<_, _, _, E, _, _>(newline, newline)(i1) { | |
| 34 | + Ok((body, _)) => { | |
| 35 | + return Ok(( | |
| 36 | + &[], | |
| 37 | + ( | |
| 38 | + &i[0usize..consumed_bytes].as_bstr(), | |
| 39 | + (!body.is_empty()).then(|| body.as_bstr()), | |
| 40 | + ), | |
| 41 | + )); | |
| 42 | + } | |
| 43 | + Err(_) => match i1.get(1..) { | |
| 44 | + Some(next) => { | |
| 45 | + consumed_bytes += 1; | |
| 46 | + next | |
| 47 | + } | |
| 48 | + None => break, | |
| 49 | + }, | |
| 38 | 50 | } |
| 39 | − Err(_) => match i1.get(1..) { | |
| 40 | − Some(next) => next, | |
| 41 | − None => break, | |
| 42 | − }, | |
| 43 | − }, | |
| 51 | + } | |
| 44 | 52 | Err(_) => match c.get(1..) { |
| 45 | − Some(next) => next, | |
| 53 | + Some(next) => { | |
| 54 | + consumed_bytes += 1; | |
| 55 | + next | |
| 56 | + } | |
| 46 | 57 | None => break, |
| 47 | 58 | }, |
| 48 | 59 | }; |
| @@ -52,7 +63,7 @@ mod decode { · 3 unmodified lines | ||
| 52 | 63 | |
| 53 | 64 | /// Returns title and body, without separator |
| 54 | 65 | pub fn bytes(message: &[u8]) -> (&BStr, Option<&BStr>) { |
| 55 | − all_consuming(nomfoo::<()>)(message).expect("cannot fail").1 | |
| 66 | + all_consuming(subject_and_body::<()>)(message).expect("cannot fail").1 | |
| 56 | 67 | } |
| 57 | 68 | } |
| 58 | 69 | |