…showing that we as always want some greedy parsing based on parsers, not based on input.
Showing the changes to git-object/src/commit (1 of 4 files). Show all
Unified · Split
| @@ -1,15 +1,30 @@ | |||
| 1 | use crate::bstr::{BStr, BString, ByteSlice, ByteVec}; | ||
| 2 | use crate::commit::MessageRef; | ||
| 3 | use std::borrow::Cow; | 1 | use std::borrow::Cow; |
| 4 | 2 | ||
| 3 | use crate::{ | ||
| 4 | bstr::{BStr, BString, ByteSlice, ByteVec}, | ||
| 5 | commit::MessageRef, | ||
| 6 | }; | ||
| 7 | |||
| 5 | mod decode { | 8 | mod decode { |
| 6 | use crate::bstr::BStr; | 9 | use nom::{ |
| 7 | use nom::error::ParseError; | 10 | branch::alt, |
| 8 | use nom::IResult; | 11 | bytes::complete::{tag, take_while}, |
| 12 | combinator::map, | ||
| 13 | error::ParseError, | ||
| 14 | sequence::{pair, terminated}, | ||
| 15 | IResult, | ||
| 16 | }; | ||
| 17 | |||
| 18 | use crate::bstr::{BStr, ByteSlice}; | ||
| 9 | 19 | ||
| 20 | pub fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> { | ||
| 21 | alt((tag(b"\r\n"), tag(b"\n")))(i) | ||
| 22 | } | ||
| 10 | /// Returns title and body, without separator | 23 | /// Returns title and body, without separator |
| 11 | pub fn bytes<'a, E: ParseError<&'a [u8]>>(_i: &'a [u8]) -> IResult<&[u8], (&'a BStr, &'a BStr), E> { | 24 | pub fn bytes<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&[u8], &'a BStr, E> { |
| 12 | todo!("actual decoding") | 25 | map(terminated(take_while(|c| c != b'\n'), pair(newline, newline)), |t| { |
| 26 | t.as_bstr() | ||
| 27 | })(i) | ||
| 13 | } | 28 | } |
| 14 | } | 29 | } |
| 15 | 30 | ||
| @@ -18,10 +33,9 @@ impl<'a> MessageRef<'a> { · 2 unmodified lines | |||
| 18 | /// | 33 | /// |
| 19 | /// Note that this cannot fail as everything will be interpreted as title if there is no body separator. | 34 | /// Note that this cannot fail as everything will be interpreted as title if there is no body separator. |
| 20 | pub fn from_bytes(input: &'a [u8]) -> Self { | 35 | pub fn from_bytes(input: &'a [u8]) -> Self { |
| 21 | let (rest, (title, body)) = decode::bytes::<()>(input) | 36 | let (title, body) = decode::bytes::<()>(input) |
| 22 | .map(|(i, (title, body))| (i, (title, Some(body)))) | 37 | .map(|(body, title)| (title, Some(body.as_bstr()))) |
| 23 | .unwrap_or_else(|_| (&[], (input.as_bstr(), None))); | 38 | .unwrap_or_else(|_| (input.as_bstr(), None)); |
| 24 | debug_assert!(rest.is_empty(), "all consuming message parsing"); | ||
| 25 | MessageRef { title, body } | 39 | MessageRef { title, body } |
| 26 | } | 40 | } |
| 27 | /// Produce a short commit summary for the message title. | 41 | /// Produce a short commit summary for the message title. |