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 | mod decode { | 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 | use crate::bstr::{BStr, ByteSlice}; | 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 | fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> { | 20 | fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> { |
| 19 | alt((tag(b"\r\n"), tag(b"\n")))(i) | 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 | let mut c = i; | 27 | let mut c = i; |
| 28 | let mut consumed_bytes = 0; | ||
| 24 | while !c.is_empty() { | 29 | while !c.is_empty() { |
| 25 | c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) { | 30 | c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) { |
| 26 | Ok((i1, segment)) => match pair::<_, _, _, E, _, _>(newline, newline)(i1) { | 31 | Ok((i1, segment)) => { |
| 27 | Ok((body, _)) => { | 32 | consumed_bytes += segment.len(); |
| 28 | // SAFETY: the pointers are pointing to the same slice. | 33 | match pair::<_, _, _, E, _, _>(newline, newline)(i1) { |
| 29 | #[allow(unsafe_code)] | 34 | Ok((body, _)) => { |
| 30 | let consumed_bytes = unsafe { segment.as_ptr_range().end.offset_from(i.as_ptr()) }; | 35 | return Ok(( |
| 31 | return Ok(( | 36 | &[], |
| 32 | &[], | 37 | ( |
| 33 | ( | 38 | &i[0usize..consumed_bytes].as_bstr(), |
| 34 | &i[0usize..consumed_bytes.try_into().expect("positive offset")].as_bstr(), | 39 | (!body.is_empty()).then(|| body.as_bstr()), |
| 35 | (!body.is_empty()).then(|| body.as_bstr()), | 40 | ), |
| 36 | ), | 41 | )); |
| 37 | )); | 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..) { | 51 | } |
| 40 | Some(next) => next, | ||
| 41 | None => break, | ||
| 42 | }, | ||
| 43 | }, | ||
| 44 | Err(_) => match c.get(1..) { | 52 | Err(_) => match c.get(1..) { |
| 45 | Some(next) => next, | 53 | Some(next) => { |
| 54 | consumed_bytes += 1; | ||
| 55 | next | ||
| 56 | } | ||
| 46 | None => break, | 57 | None => break, |
| 47 | }, | 58 | }, |
| 48 | }; | 59 | }; |
| @@ -52,7 +63,7 @@ mod decode { · 3 unmodified lines | |||
| 52 | 63 | ||
| 53 | /// Returns title and body, without separator | 64 | /// Returns title and body, without separator |
| 54 | pub fn bytes(message: &[u8]) -> (&BStr, Option<&BStr>) { | 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 | ||