]> git.proxmox.com Git - rustc.git/blame - vendor/gix-object/src/commit/message/decode.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / vendor / gix-object / src / commit / message / decode.rs
CommitLineData
781aab86
FG
1use winnow::{
2 combinator::{alt, eof, preceded, rest, terminated},
3 error::ParserError,
4 prelude::*,
5 stream::{Offset, Stream},
4b012472 6 token::take_till,
0a29b90c
FG
7};
8
9use crate::bstr::{BStr, ByteSlice};
10
781aab86
FG
11pub(crate) fn newline<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<&'a [u8], E> {
12 alt((b"\n", b"\r\n")).parse_next(i)
0a29b90c
FG
13}
14
781aab86
FG
15fn subject_and_body<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<(&'a BStr, Option<&'a BStr>), E> {
16 let start_i = *i;
17 let start = i.checkpoint();
18 while !i.is_empty() {
4b012472 19 match take_till::<_, _, E>(1.., |c| c == b'\n' || c == b'\r').parse_next(i) {
781aab86
FG
20 Ok(_) => {
21 let consumed_bytes = i.offset_from(&start);
22 match preceded((newline::<E>, newline::<E>), rest).parse_next(i) {
23 Ok(body) => {
24 let body = (!body.is_empty()).then(|| body.as_bstr());
25 return Ok((start_i[0usize..consumed_bytes].as_bstr(), body));
0a29b90c 26 }
781aab86
FG
27 Err(_) => match i.next_token() {
28 Some(_) => {}
0a29b90c
FG
29 None => break,
30 },
31 }
32 }
781aab86
FG
33 Err(_) => match i.next_token() {
34 Some(_) => {}
0a29b90c
FG
35 None => break,
36 },
781aab86 37 }
0a29b90c 38 }
781aab86
FG
39
40 i.reset(start);
41 rest.map(|r: &[u8]| (r.as_bstr(), None)).parse_next(i)
0a29b90c
FG
42}
43
44/// Returns title and body, without separator
781aab86
FG
45pub fn message(mut input: &[u8]) -> (&BStr, Option<&BStr>) {
46 terminated(subject_and_body::<()>, eof)
47 .parse_next(&mut input)
48 .expect("cannot fail")
0a29b90c 49}