summaryrefslogtreecommitdiffstats
path: root/vendor/gix-object/src/commit
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-object/src/commit')
-rw-r--r--vendor/gix-object/src/commit/decode.rs116
-rw-r--r--vendor/gix-object/src/commit/message/body.rs43
-rw-r--r--vendor/gix-object/src/commit/message/decode.rs70
-rw-r--r--vendor/gix-object/src/commit/mod.rs45
-rw-r--r--vendor/gix-object/src/commit/ref_iter.rs155
-rw-r--r--vendor/gix-object/src/commit/write.rs4
6 files changed, 274 insertions, 159 deletions
diff --git a/vendor/gix-object/src/commit/decode.rs b/vendor/gix-object/src/commit/decode.rs
index 821feaabb..0b8243ef3 100644
--- a/vendor/gix-object/src/commit/decode.rs
+++ b/vendor/gix-object/src/commit/decode.rs
@@ -1,71 +1,71 @@
use std::borrow::Cow;
-use nom::{
- branch::alt,
- bytes::complete::{is_not, tag},
- combinator::{all_consuming, opt},
- error::{context, ContextError, ParseError},
- multi::many0,
- IResult, Parser,
-};
use smallvec::SmallVec;
+use winnow::{
+ combinator::{alt, eof, opt, preceded, repeat, rest, terminated},
+ error::{AddContext, ParserError, StrContext},
+ prelude::*,
+ token::take_till1,
+};
use crate::{parse, parse::NL, BStr, ByteSlice, CommitRef};
-pub fn message<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a BStr, E> {
+pub fn message<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
+ i: &mut &'a [u8],
+) -> PResult<&'a BStr, E> {
if i.is_empty() {
// newline + [message]
- return Err(nom::Err::Error(E::add_context(
- i,
- "newline + <message>",
- E::from_error_kind(i, nom::error::ErrorKind::Eof),
- )));
+ return Err(
+ winnow::error::ErrMode::from_error_kind(i, winnow::error::ErrorKind::Eof)
+ .add_context(i, StrContext::Expected("newline + <message>".into())),
+ );
}
- let (i, _) = context("a newline separates headers from the message", tag(NL))(i)?;
- Ok((&[], i.as_bstr()))
+ preceded(NL, rest.map(ByteSlice::as_bstr))
+ .context(StrContext::Expected(
+ "a newline separates headers from the message".into(),
+ ))
+ .parse_next(i)
}
-pub fn commit<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
- i: &'a [u8],
-) -> IResult<&'a [u8], CommitRef<'_>, E> {
- let (i, tree) = context("tree <40 lowercase hex char>", |i| {
- parse::header_field(i, b"tree", parse::hex_hash)
- })(i)?;
- let (i, parents) = context(
- "zero or more 'parent <40 lowercase hex char>'",
- many0(|i| parse::header_field(i, b"parent", parse::hex_hash)),
- )(i)?;
- let (i, author) = context("author <signature>", |i| {
- parse::header_field(i, b"author", parse::signature)
- })(i)?;
- let (i, committer) = context("committer <signature>", |i| {
- parse::header_field(i, b"committer", parse::signature)
- })(i)?;
- let (i, encoding) = context(
- "encoding <encoding>",
- opt(|i| parse::header_field(i, b"encoding", is_not(NL))),
- )(i)?;
- let (i, extra_headers) = context(
- "<field> <single-line|multi-line>",
- many0(alt((
- parse::any_header_field_multi_line.map(|(k, o)| (k.as_bstr(), Cow::Owned(o))),
- |i| {
- parse::any_header_field(i, is_not(NL)).map(|(i, (k, o))| (i, (k.as_bstr(), Cow::Borrowed(o.as_bstr()))))
+pub fn commit<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
+ i: &mut &'a [u8],
+) -> PResult<CommitRef<'a>, E> {
+ (
+ (|i: &mut _| parse::header_field(i, b"tree", parse::hex_hash))
+ .context(StrContext::Expected("tree <40 lowercase hex char>".into())),
+ repeat(0.., |i: &mut _| parse::header_field(i, b"parent", parse::hex_hash))
+ .map(|p: Vec<_>| p)
+ .context(StrContext::Expected(
+ "zero or more 'parent <40 lowercase hex char>'".into(),
+ )),
+ (|i: &mut _| parse::header_field(i, b"author", parse::signature))
+ .context(StrContext::Expected("author <signature>".into())),
+ (|i: &mut _| parse::header_field(i, b"committer", parse::signature))
+ .context(StrContext::Expected("committer <signature>".into())),
+ opt(|i: &mut _| parse::header_field(i, b"encoding", take_till1(NL)))
+ .context(StrContext::Expected("encoding <encoding>".into())),
+ repeat(
+ 0..,
+ alt((
+ parse::any_header_field_multi_line.map(|(k, o)| (k.as_bstr(), Cow::Owned(o))),
+ |i: &mut _| {
+ parse::any_header_field(i, take_till1(NL)).map(|(k, o)| (k.as_bstr(), Cow::Borrowed(o.as_bstr())))
+ },
+ )),
+ )
+ .context(StrContext::Expected("<field> <single-line|multi-line>".into())),
+ terminated(message, eof),
+ )
+ .map(
+ |(tree, parents, author, committer, encoding, extra_headers, message)| CommitRef {
+ tree,
+ parents: SmallVec::from(parents),
+ author,
+ committer,
+ encoding: encoding.map(ByteSlice::as_bstr),
+ message,
+ extra_headers,
},
- ))),
- )(i)?;
- let (i, message) = all_consuming(message)(i)?;
-
- Ok((
- i,
- CommitRef {
- tree,
- parents: SmallVec::from(parents),
- author,
- committer,
- encoding: encoding.map(ByteSlice::as_bstr),
- message,
- extra_headers,
- },
- ))
+ )
+ .parse_next(i)
}
diff --git a/vendor/gix-object/src/commit/message/body.rs b/vendor/gix-object/src/commit/message/body.rs
index 855f031be..6301bf30e 100644
--- a/vendor/gix-object/src/commit/message/body.rs
+++ b/vendor/gix-object/src/commit/message/body.rs
@@ -1,11 +1,10 @@
use std::ops::Deref;
-use nom::{
- bytes::complete::{tag, take_until1},
- combinator::all_consuming,
- error::{ErrorKind, ParseError},
- sequence::terminated,
- IResult,
+use winnow::{
+ combinator::{eof, rest, separated_pair, terminated},
+ error::{ErrorKind, ParserError},
+ prelude::*,
+ token::take_until1,
};
use crate::{
@@ -32,12 +31,14 @@ pub struct TrailerRef<'a> {
pub value: &'a BStr,
}
-fn parse_single_line_trailer<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&'a BStr, &'a BStr), E> {
- let (value, token) = terminated(take_until1(b":".as_ref()), tag(b": "))(i.trim_end())?;
+fn parse_single_line_trailer<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<(&'a BStr, &'a BStr), E> {
+ *i = i.trim_end();
+ let (token, value) = separated_pair(take_until1(b":".as_ref()), b": ", rest).parse_next(i)?;
+
if token.trim_end().len() != token.len() || value.trim_start().len() != value.len() {
- Err(nom::Err::Failure(E::from_error_kind(i, ErrorKind::Fail)))
+ Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Fail).cut())
} else {
- Ok((&[], (token.as_bstr(), value.as_bstr())))
+ Ok((token.as_bstr(), value.as_bstr()))
}
}
@@ -48,15 +49,15 @@ impl<'a> Iterator for Trailers<'a> {
if self.cursor.is_empty() {
return None;
}
- for line in self.cursor.lines_with_terminator() {
+ for mut line in self.cursor.lines_with_terminator() {
self.cursor = &self.cursor[line.len()..];
- if let Some(trailer) =
- all_consuming(parse_single_line_trailer::<()>)(line)
- .ok()
- .map(|(_, (token, value))| TrailerRef {
- token: token.trim().as_bstr(),
- value: value.trim().as_bstr(),
- })
+ if let Some(trailer) = terminated(parse_single_line_trailer::<()>, eof)
+ .parse_next(&mut line)
+ .ok()
+ .map(|(token, value)| TrailerRef {
+ token: token.trim().as_bstr(),
+ value: value.trim().as_bstr(),
+ })
{
return Some(trailer);
}
@@ -118,7 +119,7 @@ mod test_parse_trailer {
use super::*;
fn parse(input: &str) -> (&BStr, &BStr) {
- parse_single_line_trailer::<()>(input.as_bytes()).unwrap().1
+ parse_single_line_trailer::<()>.parse_peek(input.as_bytes()).unwrap().1
}
#[test]
@@ -141,8 +142,8 @@ mod test_parse_trailer {
#[test]
fn extra_whitespace_before_token_or_value_is_error() {
- assert!(parse_single_line_trailer::<()>(b"foo : bar").is_err());
- assert!(parse_single_line_trailer::<()>(b"foo: bar").is_err())
+ assert!(parse_single_line_trailer::<()>.parse_peek(b"foo : bar").is_err());
+ assert!(parse_single_line_trailer::<()>.parse_peek(b"foo: bar").is_err())
}
#[test]
diff --git a/vendor/gix-object/src/commit/message/decode.rs b/vendor/gix-object/src/commit/message/decode.rs
index 6224909bd..8038009b4 100644
--- a/vendor/gix-object/src/commit/message/decode.rs
+++ b/vendor/gix-object/src/commit/message/decode.rs
@@ -1,57 +1,49 @@
-use nom::{
- branch::alt,
- bytes::complete::{tag, take_till1},
- combinator::all_consuming,
- error::ParseError,
- sequence::pair,
- IResult,
+use winnow::{
+ combinator::{alt, eof, preceded, rest, terminated},
+ error::ParserError,
+ prelude::*,
+ stream::{Offset, Stream},
+ token::take_till1,
};
use crate::bstr::{BStr, ByteSlice};
-pub(crate) fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {
- alt((tag(b"\r\n"), tag(b"\n")))(i)
+pub(crate) fn newline<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<&'a [u8], E> {
+ alt((b"\n", b"\r\n")).parse_next(i)
}
-fn subject_and_body<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&'a BStr, Option<&'a BStr>), E> {
- let mut c = i;
- let mut consumed_bytes = 0;
- while !c.is_empty() {
- c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) {
- Ok((i1, segment)) => {
- consumed_bytes += segment.len();
- match pair::<_, _, _, E, _, _>(newline, newline)(i1) {
- Ok((body, _)) => {
- return Ok((
- &[],
- (
- i[0usize..consumed_bytes].as_bstr(),
- (!body.is_empty()).then(|| body.as_bstr()),
- ),
- ));
+fn subject_and_body<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<(&'a BStr, Option<&'a BStr>), E> {
+ let start_i = *i;
+ let start = i.checkpoint();
+ while !i.is_empty() {
+ match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r').parse_next(i) {
+ Ok(_) => {
+ let consumed_bytes = i.offset_from(&start);
+ match preceded((newline::<E>, newline::<E>), rest).parse_next(i) {
+ Ok(body) => {
+ let body = (!body.is_empty()).then(|| body.as_bstr());
+ return Ok((start_i[0usize..consumed_bytes].as_bstr(), body));
}
- Err(_) => match i1.get(1..) {
- Some(next) => {
- consumed_bytes += 1;
- next
- }
+ Err(_) => match i.next_token() {
+ Some(_) => {}
None => break,
},
}
}
- Err(_) => match c.get(1..) {
- Some(next) => {
- consumed_bytes += 1;
- next
- }
+ Err(_) => match i.next_token() {
+ Some(_) => {}
None => break,
},
- };
+ }
}
- Ok((&[], (i.as_bstr(), None)))
+
+ i.reset(start);
+ rest.map(|r: &[u8]| (r.as_bstr(), None)).parse_next(i)
}
/// Returns title and body, without separator
-pub fn message(input: &[u8]) -> (&BStr, Option<&BStr>) {
- all_consuming(subject_and_body::<()>)(input).expect("cannot fail").1
+pub fn message(mut input: &[u8]) -> (&BStr, Option<&BStr>) {
+ terminated(subject_and_body::<()>, eof)
+ .parse_next(&mut input)
+ .expect("cannot fail")
}
diff --git a/vendor/gix-object/src/commit/mod.rs b/vendor/gix-object/src/commit/mod.rs
index 9e135df28..b3de9b0a4 100644
--- a/vendor/gix-object/src/commit/mod.rs
+++ b/vendor/gix-object/src/commit/mod.rs
@@ -1,4 +1,6 @@
-use bstr::{BStr, ByteSlice};
+use std::ops::Range;
+
+use bstr::{BStr, BString, ByteSlice};
use crate::{Commit, CommitRef, TagRef};
@@ -21,16 +23,49 @@ pub struct MessageRef<'a> {
pub body: Option<&'a BStr>,
}
+/// The raw commit data, parseable by [`CommitRef`] or [`Commit`], which was fed into a program to produce a signature.
+///
+/// See [`extract_signature()`](crate::CommitRefIter::signature()) for how to obtain it.
+// TODO: implement `std::io::Read` to avoid allocations
+#[derive(PartialEq, Eq, Debug, Hash, Clone)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+pub struct SignedData<'a> {
+ /// The raw commit data that includes the signature.
+ data: &'a [u8],
+ /// The byte range at which we find the signature. All but the signature is the data that was signed.
+ signature_range: Range<usize>,
+}
+
+impl SignedData<'_> {
+ /// Convenience method to obtain a copy of the signed data.
+ pub fn to_bstring(&self) -> BString {
+ let mut buf = BString::from(&self.data[..self.signature_range.start]);
+ buf.extend_from_slice(&self.data[self.signature_range.end..]);
+ buf
+ }
+}
+
+impl From<SignedData<'_>> for BString {
+ fn from(value: SignedData<'_>) -> Self {
+ value.to_bstring()
+ }
+}
+
///
pub mod ref_iter;
mod write;
+/// Lifecycle
impl<'a> CommitRef<'a> {
/// Deserialize a commit from the given `data` bytes while avoiding most allocations.
- pub fn from_bytes(data: &'a [u8]) -> Result<CommitRef<'a>, crate::decode::Error> {
- decode::commit(data).map(|(_, t)| t).map_err(crate::decode::Error::from)
+ pub fn from_bytes(mut data: &'a [u8]) -> Result<CommitRef<'a>, crate::decode::Error> {
+ decode::commit(&mut data).map_err(crate::decode::Error::with_err)
}
+}
+
+/// Access
+impl<'a> CommitRef<'a> {
/// Return the `tree` fields hash digest.
pub fn tree(&self) -> gix_hash::ObjectId {
gix_hash::ObjectId::from_hex(self.tree).expect("prior validation of tree hash during parsing")
@@ -45,7 +80,7 @@ impl<'a> CommitRef<'a> {
/// Returns a convenient iterator over all extra headers.
pub fn extra_headers(&self) -> crate::commit::ExtraHeaders<impl Iterator<Item = (&BStr, &BStr)>> {
- crate::commit::ExtraHeaders::new(self.extra_headers.iter().map(|(k, v)| (*k, v.as_ref())))
+ ExtraHeaders::new(self.extra_headers.iter().map(|(k, v)| (*k, v.as_ref())))
}
/// Return the author, with whitespace trimmed.
@@ -68,7 +103,7 @@ impl<'a> CommitRef<'a> {
}
/// Returns the time at which this commit was created.
- pub fn time(&self) -> gix_actor::Time {
+ pub fn time(&self) -> gix_date::Time {
self.committer.time
}
}
diff --git a/vendor/gix-object/src/commit/ref_iter.rs b/vendor/gix-object/src/commit/ref_iter.rs
index 454f69ac0..4401384ca 100644
--- a/vendor/gix-object/src/commit/ref_iter.rs
+++ b/vendor/gix-object/src/commit/ref_iter.rs
@@ -1,15 +1,21 @@
-use std::borrow::Cow;
+use std::{borrow::Cow, ops::Range};
use bstr::BStr;
use gix_hash::{oid, ObjectId};
-use nom::{
- branch::alt,
- bytes::complete::is_not,
- combinator::{all_consuming, opt},
- error::context,
+use winnow::{
+ combinator::{alt, eof, opt, terminated},
+ error::StrContext,
+ prelude::*,
+ token::take_till1,
};
-use crate::{bstr::ByteSlice, commit::decode, parse, parse::NL, CommitRefIter};
+use crate::{
+ bstr::ByteSlice,
+ commit::{decode, SignedData},
+ parse,
+ parse::NL,
+ CommitRefIter,
+};
#[derive(Copy, Clone)]
pub(crate) enum SignatureKind {
@@ -30,6 +36,7 @@ pub(crate) enum State {
Message,
}
+/// Lifecycle
impl<'a> CommitRefIter<'a> {
/// Create a commit iterator from data.
pub fn from_bytes(data: &'a [u8]) -> CommitRefIter<'a> {
@@ -38,6 +45,37 @@ impl<'a> CommitRefIter<'a> {
state: State::default(),
}
}
+}
+
+/// Access
+impl<'a> CommitRefIter<'a> {
+ /// Parse `data` as commit and return its PGP signature, along with *all non-signature* data as [`SignedData`], or `None`
+ /// if the commit isn't signed.
+ ///
+ /// This allows the caller to validate the signature by passing the signed data along with the signature back to the program
+ /// that created it.
+ pub fn signature(data: &'a [u8]) -> Result<Option<(Cow<'a, BStr>, SignedData<'a>)>, crate::decode::Error> {
+ let mut signature_and_range = None;
+
+ let raw_tokens = CommitRefIterRaw {
+ data,
+ state: State::default(),
+ offset: 0,
+ };
+ for token in raw_tokens {
+ let token = token?;
+ if let Token::ExtraHeader((name, value)) = &token.token {
+ if *name == "gpgsig" {
+ // keep track of the signature range alongside the signature data,
+ // because all but the signature is the signed data.
+ signature_and_range = Some((value.clone(), token.token_range));
+ break;
+ }
+ }
+ }
+
+ Ok(signature_and_range.map(|(sig, signature_range)| (sig, SignedData { data, signature_range })))
+ }
/// Returns the object id of this commits tree if it is the first function called and if there is no error in decoding
/// the data.
@@ -106,7 +144,7 @@ impl<'a> CommitRefIter<'a> {
_ => None,
})
.transpose()
- .map(|msg| msg.unwrap_or_default())
+ .map(Option::unwrap_or_default)
}
}
@@ -115,13 +153,21 @@ fn missing_field() -> crate::decode::Error {
}
impl<'a> CommitRefIter<'a> {
+ #[inline]
fn next_inner(i: &'a [u8], state: &mut State) -> Result<(&'a [u8], Token<'a>), crate::decode::Error> {
+ Self::next_inner_(i, state).map_err(crate::decode::Error::with_err)
+ }
+
+ fn next_inner_(
+ mut i: &'a [u8],
+ state: &mut State,
+ ) -> Result<(&'a [u8], Token<'a>), winnow::error::ErrMode<crate::decode::ParseError>> {
use State::*;
Ok(match state {
Tree => {
- let (i, tree) = context("tree <40 lowercase hex char>", |i| {
- parse::header_field(i, b"tree", parse::hex_hash)
- })(i)?;
+ let tree = (|i: &mut _| parse::header_field(i, b"tree", parse::hex_hash))
+ .context(StrContext::Expected("tree <40 lowercase hex char>".into()))
+ .parse_next(&mut i)?;
*state = State::Parents;
(
i,
@@ -131,10 +177,9 @@ impl<'a> CommitRefIter<'a> {
)
}
Parents => {
- let (i, parent) = context(
- "commit <40 lowercase hex char>",
- opt(|i| parse::header_field(i, b"parent", parse::hex_hash)),
- )(i)?;
+ let parent = opt(|i: &mut _| parse::header_field(i, b"parent", parse::hex_hash))
+ .context(StrContext::Expected("commit <40 lowercase hex char>".into()))
+ .parse_next(&mut i)?;
match parent {
Some(parent) => (
i,
@@ -146,7 +191,7 @@ impl<'a> CommitRefIter<'a> {
*state = State::Signature {
of: SignatureKind::Author,
};
- return Self::next_inner(i, state);
+ return Self::next_inner_(i, state);
}
}
}
@@ -162,7 +207,9 @@ impl<'a> CommitRefIter<'a> {
(&b"committer"[..], "committer <signature>")
}
};
- let (i, signature) = context(err_msg, |i| parse::header_field(i, field_name, parse::signature))(i)?;
+ let signature = (|i: &mut _| parse::header_field(i, field_name, parse::signature))
+ .context(StrContext::Expected(err_msg.into()))
+ .parse_next(&mut i)?;
(
i,
match who {
@@ -172,37 +219,35 @@ impl<'a> CommitRefIter<'a> {
)
}
Encoding => {
- let (i, encoding) = context(
- "encoding <encoding>",
- opt(|i| parse::header_field(i, b"encoding", is_not(NL))),
- )(i)?;
+ let encoding = opt(|i: &mut _| parse::header_field(i, b"encoding", take_till1(NL)))
+ .context(StrContext::Expected("encoding <encoding>".into()))
+ .parse_next(&mut i)?;
*state = State::ExtraHeaders;
match encoding {
Some(encoding) => (i, Token::Encoding(encoding.as_bstr())),
- None => return Self::next_inner(i, state),
+ None => return Self::next_inner_(i, state),
}
}
ExtraHeaders => {
- let (i, extra_header) = context(
- "<field> <single-line|multi-line>",
- opt(alt((
- |i| parse::any_header_field_multi_line(i).map(|(i, (k, o))| (i, (k.as_bstr(), Cow::Owned(o)))),
- |i| {
- parse::any_header_field(i, is_not(NL))
- .map(|(i, (k, o))| (i, (k.as_bstr(), Cow::Borrowed(o.as_bstr()))))
- },
- ))),
- )(i)?;
+ let extra_header = opt(alt((
+ |i: &mut _| parse::any_header_field_multi_line(i).map(|(k, o)| (k.as_bstr(), Cow::Owned(o))),
+ |i: &mut _| {
+ parse::any_header_field(i, take_till1(NL))
+ .map(|(k, o)| (k.as_bstr(), Cow::Borrowed(o.as_bstr())))
+ },
+ )))
+ .context(StrContext::Expected("<field> <single-line|multi-line>".into()))
+ .parse_next(&mut i)?;
match extra_header {
Some(extra_header) => (i, Token::ExtraHeader(extra_header)),
None => {
*state = State::Message;
- return Self::next_inner(i, state);
+ return Self::next_inner_(i, state);
}
}
}
Message => {
- let (i, message) = all_consuming(decode::message)(i)?;
+ let message = terminated(decode::message, eof).parse_next(&mut i)?;
debug_assert!(
i.is_empty(),
"we should have consumed all data - otherwise iter may go forever"
@@ -233,6 +278,48 @@ impl<'a> Iterator for CommitRefIter<'a> {
}
}
+/// A variation of [`CommitRefIter`] that return's [`RawToken`]s instead.
+struct CommitRefIterRaw<'a> {
+ data: &'a [u8],
+ state: State,
+ offset: usize,
+}
+
+impl<'a> Iterator for CommitRefIterRaw<'a> {
+ type Item = Result<RawToken<'a>, crate::decode::Error>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.data.is_empty() {
+ return None;
+ }
+ match CommitRefIter::next_inner(self.data, &mut self.state) {
+ Ok((remaining, token)) => {
+ let consumed = self.data.len() - remaining.len();
+ let start = self.offset;
+ let end = start + consumed;
+ self.offset = end;
+
+ self.data = remaining;
+ Some(Ok(RawToken {
+ token,
+ token_range: start..end,
+ }))
+ }
+ Err(err) => {
+ self.data = &[];
+ Some(Err(err))
+ }
+ }
+ }
+}
+
+/// A combination of a parsed [`Token`] as well as the range of bytes that were consumed to parse it.
+struct RawToken<'a> {
+ /// The parsed token.
+ token: Token<'a>,
+ token_range: Range<usize>,
+}
+
/// A token returned by the [commit iterator][CommitRefIter].
#[allow(missing_docs)]
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
diff --git a/vendor/gix-object/src/commit/write.rs b/vendor/gix-object/src/commit/write.rs
index e498789a2..667d25763 100644
--- a/vendor/gix-object/src/commit/write.rs
+++ b/vendor/gix-object/src/commit/write.rs
@@ -6,7 +6,7 @@ use crate::{encode, encode::NL, Commit, CommitRef, Kind};
impl crate::WriteTo for Commit {
/// Serializes this instance to `out` in the git serialization format.
- fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
+ fn write_to(&self, mut out: &mut dyn io::Write) -> io::Result<()> {
encode::trusted_header_id(b"tree", &self.tree, &mut out)?;
for parent in &self.parents {
encode::trusted_header_id(b"parent", parent, &mut out)?;
@@ -52,7 +52,7 @@ impl crate::WriteTo for Commit {
impl<'a> crate::WriteTo for CommitRef<'a> {
/// Serializes this instance to `out` in the git serialization format.
- fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
+ fn write_to(&self, mut out: &mut dyn io::Write) -> io::Result<()> {
encode::trusted_header_id(b"tree", &self.tree(), &mut out)?;
for parent in self.parents() {
encode::trusted_header_id(b"parent", &parent, &mut out)?;