]> git.proxmox.com Git - rustc.git/blob - vendor/gix-object/src/commit/decode.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / vendor / gix-object / src / commit / decode.rs
1 use std::borrow::Cow;
2
3 use smallvec::SmallVec;
4 use winnow::{
5 combinator::{alt, eof, opt, preceded, repeat, rest, terminated},
6 error::{AddContext, ParserError, StrContext},
7 prelude::*,
8 token::take_till1,
9 };
10
11 use crate::{parse, parse::NL, BStr, ByteSlice, CommitRef};
12
13 pub fn message<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
14 i: &mut &'a [u8],
15 ) -> PResult<&'a BStr, E> {
16 if i.is_empty() {
17 // newline + [message]
18 return Err(
19 winnow::error::ErrMode::from_error_kind(i, winnow::error::ErrorKind::Eof)
20 .add_context(i, StrContext::Expected("newline + <message>".into())),
21 );
22 }
23 preceded(NL, rest.map(ByteSlice::as_bstr))
24 .context(StrContext::Expected(
25 "a newline separates headers from the message".into(),
26 ))
27 .parse_next(i)
28 }
29
30 pub fn commit<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
31 i: &mut &'a [u8],
32 ) -> PResult<CommitRef<'a>, E> {
33 (
34 (|i: &mut _| parse::header_field(i, b"tree", parse::hex_hash))
35 .context(StrContext::Expected("tree <40 lowercase hex char>".into())),
36 repeat(0.., |i: &mut _| parse::header_field(i, b"parent", parse::hex_hash))
37 .map(|p: Vec<_>| p)
38 .context(StrContext::Expected(
39 "zero or more 'parent <40 lowercase hex char>'".into(),
40 )),
41 (|i: &mut _| parse::header_field(i, b"author", parse::signature))
42 .context(StrContext::Expected("author <signature>".into())),
43 (|i: &mut _| parse::header_field(i, b"committer", parse::signature))
44 .context(StrContext::Expected("committer <signature>".into())),
45 opt(|i: &mut _| parse::header_field(i, b"encoding", take_till1(NL)))
46 .context(StrContext::Expected("encoding <encoding>".into())),
47 repeat(
48 0..,
49 alt((
50 parse::any_header_field_multi_line.map(|(k, o)| (k.as_bstr(), Cow::Owned(o))),
51 |i: &mut _| {
52 parse::any_header_field(i, take_till1(NL)).map(|(k, o)| (k.as_bstr(), Cow::Borrowed(o.as_bstr())))
53 },
54 )),
55 )
56 .context(StrContext::Expected("<field> <single-line|multi-line>".into())),
57 terminated(message, eof),
58 )
59 .map(
60 |(tree, parents, author, committer, encoding, extra_headers, message)| CommitRef {
61 tree,
62 parents: SmallVec::from(parents),
63 author,
64 committer,
65 encoding: encoding.map(ByteSlice::as_bstr),
66 message,
67 extra_headers,
68 },
69 )
70 .parse_next(i)
71 }