…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 | 1 | use std::borrow::Cow; |
| 4 | 2 | |
| 3 | +use crate::{ | |
| 4 | + bstr::{BStr, BString, ByteSlice, ByteVec}, | |
| 5 | + commit::MessageRef, | |
| 6 | +}; | |
| 7 | + | |
| 5 | 8 | mod decode { |
| 6 | − use crate::bstr::BStr; | |
| 7 | − use nom::error::ParseError; | |
| 8 | − use nom::IResult; | |
| 9 | + use nom::{ | |
| 10 | + branch::alt, | |
| 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 | 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> { | |
| 12 | − todo!("actual decoding") | |
| 24 | + pub fn bytes<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&[u8], &'a BStr, E> { | |
| 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 | 34 | /// Note that this cannot fail as everything will be interpreted as title if there is no body separator. |
| 20 | 35 | pub fn from_bytes(input: &'a [u8]) -> Self { |
| 21 | − let (rest, (title, body)) = decode::bytes::<()>(input) | |
| 22 | − .map(|(i, (title, body))| (i, (title, Some(body)))) | |
| 23 | − .unwrap_or_else(|_| (&[], (input.as_bstr(), None))); | |
| 24 | − debug_assert!(rest.is_empty(), "all consuming message parsing"); | |
| 36 | + let (title, body) = decode::bytes::<()>(input) | |
| 37 | + .map(|(body, title)| (title, Some(body.as_bstr()))) | |
| 38 | + .unwrap_or_else(|_| (input.as_bstr(), None)); | |
| 25 | 39 | MessageRef { title, body } |
| 26 | 40 | } |
| 27 | 41 | /// Produce a short commit summary for the message title. |