3 use smallvec
::SmallVec
;
5 combinator
::{alt, eof, opt, preceded, repeat, rest, terminated}
,
6 error
::{AddContext, ParserError, StrContext}
,
11 use crate::{parse, parse::NL, BStr, ByteSlice, CommitRef}
;
13 pub fn message
<'a
, E
: ParserError
<&'a
[u8]> + AddContext
<&'a
[u8], StrContext
>>(
15 ) -> PResult
<&'a BStr
, E
> {
17 // newline + [message]
19 winnow
::error
::ErrMode
::from_error_kind(i
, winnow
::error
::ErrorKind
::Eof
)
20 .add_context(i
, StrContext
::Expected("newline + <message>".into())),
23 preceded(NL
, rest
.map(ByteSlice
::as_bstr
))
24 .context(StrContext
::Expected(
25 "a newline separates headers from the message".into(),
30 pub fn commit
<'a
, E
: ParserError
<&'a
[u8]> + AddContext
<&'a
[u8], StrContext
>>(
32 ) -> PResult
<CommitRef
<'a
>, E
> {
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
))
38 .context(StrContext
::Expected(
39 "zero or more 'parent <40 lowercase hex char>'".into(),
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())),
50 parse
::any_header_field_multi_line
.map(|(k
, o
)| (k
.as_bstr(), Cow
::Owned(o
))),
52 parse
::any_header_field(i
, take_till1(NL
)).map(|(k
, o
)| (k
.as_bstr(), Cow
::Borrowed(o
.as_bstr())))
56 .context(StrContext
::Expected("<field> <single-line|multi-line>".into())),
57 terminated(message
, eof
),
60 |(tree
, parents
, author
, committer
, encoding
, extra_headers
, message
)| CommitRef
{
62 parents
: SmallVec
::from(parents
),
65 encoding
: encoding
.map(ByteSlice
::as_bstr
),