diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/gix-ref/src | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-ref/src')
26 files changed, 303 insertions, 259 deletions
diff --git a/vendor/gix-ref/src/fullname.rs b/vendor/gix-ref/src/fullname.rs index 257bbe060..5957943dc 100644 --- a/vendor/gix-ref/src/fullname.rs +++ b/vendor/gix-ref/src/fullname.rs @@ -5,44 +5,46 @@ use gix_object::bstr::{BStr, BString, ByteSlice}; use crate::{bstr::ByteVec, name::is_pseudo_ref, Category, FullName, FullNameRef, Namespace, PartialNameRef}; impl TryFrom<&str> for FullName { - type Error = gix_validate::refname::Error; + type Error = gix_validate::reference::name::Error; fn try_from(value: &str) -> Result<Self, Self::Error> { - Ok(FullName(gix_validate::refname(value.as_bytes().as_bstr())?.into())) + Ok(FullName( + gix_validate::reference::name(value.as_bytes().as_bstr())?.into(), + )) } } impl TryFrom<String> for FullName { - type Error = gix_validate::refname::Error; + type Error = gix_validate::reference::name::Error; fn try_from(value: String) -> Result<Self, Self::Error> { - gix_validate::refname(value.as_bytes().as_bstr())?; + gix_validate::reference::name(value.as_bytes().as_bstr())?; Ok(FullName(value.into())) } } impl TryFrom<&BStr> for FullName { - type Error = gix_validate::refname::Error; + type Error = gix_validate::reference::name::Error; fn try_from(value: &BStr) -> Result<Self, Self::Error> { - Ok(FullName(gix_validate::refname(value)?.into())) + Ok(FullName(gix_validate::reference::name(value)?.into())) } } impl TryFrom<BString> for FullName { - type Error = gix_validate::refname::Error; + type Error = gix_validate::reference::name::Error; fn try_from(value: BString) -> Result<Self, Self::Error> { - gix_validate::refname(value.as_ref())?; + gix_validate::reference::name(value.as_ref())?; Ok(FullName(value)) } } impl TryFrom<&BString> for FullName { - type Error = gix_validate::refname::Error; + type Error = gix_validate::reference::name::Error; fn try_from(value: &BString) -> Result<Self, Self::Error> { - gix_validate::refname(value.as_ref())?; + gix_validate::reference::name(value.as_ref())?; Ok(FullName(value.clone())) } } @@ -132,7 +134,7 @@ impl FullNameRef { if shortened.starts_with_str("refs/") { (Category::MainRef, shortened.as_bstr()).into() } else { - is_pseudo_ref(shortened).then(|| (Category::MainPseudoRef, shortened.as_bstr())) + is_pseudo_ref(shortened.into()).then(|| (Category::MainPseudoRef, shortened.as_bstr())) } } else if let Some(shortened_with_worktree_name) = name.strip_prefix(Category::LinkedPseudoRef { name: "".into() }.prefix().as_bytes()) diff --git a/vendor/gix-ref/src/name.rs b/vendor/gix-ref/src/name.rs index b21fdaf56..81b90a020 100644 --- a/vendor/gix-ref/src/name.rs +++ b/vendor/gix-ref/src/name.rs @@ -98,10 +98,10 @@ impl PartialNameRef { impl PartialName { /// Append the `component` to ourselves and validate the newly created partial path. - pub fn join(self, component: impl AsRef<[u8]>) -> Result<Self, Error> { + pub fn join(self, component: &BStr) -> Result<Self, Error> { let mut b = self.0; b.push_byte(b'/'); - b.extend(component.as_ref()); + b.extend(component.as_bytes()); gix_validate::reference::name_partial(b.as_ref())?; Ok(PartialName(b)) } @@ -263,6 +263,6 @@ impl convert::TryFrom<BString> for PartialName { /// Note that this method is disagreeing with `gix_validate` as it allows dashes '-' for some reason. /// Since partial names cannot be created with dashes inside we adjusted this as it's probably unintended or git creates pseudo-refs /// which wouldn't pass its safety checks. -pub(crate) fn is_pseudo_ref<'a>(name: impl Into<&'a BStr>) -> bool { - name.into().bytes().all(|b| b.is_ascii_uppercase() || b == b'_') +pub(crate) fn is_pseudo_ref(name: &BStr) -> bool { + name.bytes().all(|b| b.is_ascii_uppercase() || b == b'_') } diff --git a/vendor/gix-ref/src/namespace.rs b/vendor/gix-ref/src/namespace.rs index 2723052ec..34040f606 100644 --- a/vendor/gix-ref/src/namespace.rs +++ b/vendor/gix-ref/src/namespace.rs @@ -21,9 +21,8 @@ impl Namespace { gix_path::from_byte_slice(&self.0) } /// Append the given `prefix` to this namespace so it becomes usable for prefixed iteration. - pub fn into_namespaced_prefix(mut self, prefix: impl AsRef<Path>) -> PathBuf { - let path = prefix.as_ref(); - let prefix = gix_path::into_bstr(path); + pub fn into_namespaced_prefix(mut self, prefix: &Path) -> PathBuf { + let prefix = gix_path::into_bstr(prefix); self.0.push_str(prefix.as_ref()); gix_path::to_native_path_on_windows(self.0).into_owned() } @@ -36,10 +35,10 @@ impl Namespace { /// Given a `namespace` 'foo we output 'refs/namespaces/foo', and given 'foo/bar' we output 'refs/namespaces/foo/refs/namespaces/bar'. /// /// For more information, consult the [git namespace documentation](https://git-scm.com/docs/gitnamespaces). -pub fn expand<'a, Name, E>(namespace: Name) -> Result<Namespace, gix_validate::refname::Error> +pub fn expand<'a, Name, E>(namespace: Name) -> Result<Namespace, gix_validate::reference::name::Error> where Name: TryInto<&'a PartialNameRef, Error = E>, - gix_validate::refname::Error: From<E>, + gix_validate::reference::name::Error: From<E>, { let namespace = &namespace.try_into()?.0; let mut out = BString::default(); diff --git a/vendor/gix-ref/src/parse.rs b/vendor/gix-ref/src/parse.rs index 9656c8197..afbd43491 100644 --- a/vendor/gix-ref/src/parse.rs +++ b/vendor/gix-ref/src/parse.rs @@ -1,27 +1,22 @@ use gix_object::bstr::{BStr, ByteSlice}; -use nom::{ - branch::alt, - bytes::complete::{tag, take_while_m_n}, - error::ParseError, - IResult, -}; +use winnow::{combinator::alt, error::ParserError, prelude::*, token::take_while}; fn is_hex_digit_lc(b: u8) -> bool { matches!(b, b'0'..=b'9' | b'a'..=b'f') } /// Copy from https://github.com/Byron/gitoxide/blob/f270850ff92eab15258023b8e59346ec200303bd/gix-object/src/immutable/parse.rs#L64 -pub fn hex_hash<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a BStr, E> { +pub fn hex_hash<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<&'a BStr, E> { // NOTE: It's important to be able to read all hashes, do not parameterize it. Hashes can be rejected at a later stage // if needed. - take_while_m_n( - gix_hash::Kind::shortest().len_in_hex(), - gix_hash::Kind::longest().len_in_hex(), + take_while( + gix_hash::Kind::shortest().len_in_hex()..=gix_hash::Kind::longest().len_in_hex(), is_hex_digit_lc, - )(i) - .map(|(i, hex)| (i, hex.as_bstr())) + ) + .map(ByteSlice::as_bstr) + .parse_next(i) } -pub 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 fn newline<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<&'a [u8], E> { + alt((b"\r\n", b"\n")).parse_next(i) } diff --git a/vendor/gix-ref/src/peel.rs b/vendor/gix-ref/src/peel.rs index c8efb5f03..47a231df0 100644 --- a/vendor/gix-ref/src/peel.rs +++ b/vendor/gix-ref/src/peel.rs @@ -1,8 +1,9 @@ /// A function for use in [`crate::file::ReferenceExt::peel_to_id_in_place()`] to indicate no peeling should happen. +#[allow(clippy::type_complexity)] pub fn none( _id: gix_hash::ObjectId, #[allow(clippy::ptr_arg)] _buf: &mut Vec<u8>, -) -> Result<Option<(gix_object::Kind, &[u8])>, std::convert::Infallible> { +) -> Result<Option<(gix_object::Kind, &[u8])>, Box<dyn std::error::Error + Send + Sync>> { Ok(Some((gix_object::Kind::Commit, &[]))) } diff --git a/vendor/gix-ref/src/store/file/find.rs b/vendor/gix-ref/src/store/file/find.rs index 7e1fc378f..b9cf6543a 100644 --- a/vendor/gix-ref/src/store/file/find.rs +++ b/vendor/gix-ref/src/store/file/find.rs @@ -81,7 +81,7 @@ impl file::Store { "remotes", partial_name .to_owned() - .join("HEAD") + .join("HEAD".into()) .expect("HEAD is valid name") .as_ref(), None, diff --git a/vendor/gix-ref/src/store/file/log/line.rs b/vendor/gix-ref/src/store/file/log/line.rs index 99c118ea7..01de31a7c 100644 --- a/vendor/gix-ref/src/store/file/log/line.rs +++ b/vendor/gix-ref/src/store/file/log/line.rs @@ -33,9 +33,9 @@ mod write { /// Output impl Line { /// Serialize this instance to `out` in the git serialization format for ref log lines. - pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { + pub fn write_to(&self, out: &mut dyn io::Write) -> io::Result<()> { write!(out, "{} {} ", self.previous_oid, self.new_oid)?; - self.signature.write_to(&mut out)?; + self.signature.write_to(out)?; writeln!(out, "\t{}", check_newlines(self.message.as_ref())?) } } @@ -74,12 +74,11 @@ impl<'a> From<LineRef<'a>> for Line { /// pub mod decode { use gix_object::bstr::{BStr, ByteSlice}; - use nom::{ - bytes::complete::{tag, take_while}, - combinator::opt, - error::{context, ContextError, ParseError}, - sequence::{terminated, tuple}, - IResult, + use winnow::{ + combinator::{alt, eof, fail, opt, preceded, rest, terminated}, + error::{AddContext, ParserError, StrContext}, + prelude::*, + token::take_while, }; use crate::{file::log::LineRef, parse::hex_hash}; @@ -118,57 +117,57 @@ pub mod decode { impl<'a> LineRef<'a> { /// Decode a line from the given bytes which are expected to start at a hex sha. - pub fn from_bytes(input: &'a [u8]) -> Result<LineRef<'a>, Error> { - one::<()>(input).map(|(_, l)| l).map_err(|_| Error::new(input)) + pub fn from_bytes(mut input: &'a [u8]) -> Result<LineRef<'a>, Error> { + one::<()>(&mut input).map_err(|_| Error::new(input)) } } - fn message<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a BStr, E> { + fn message<'a, E: ParserError<&'a [u8]>>(i: &mut &'a [u8]) -> PResult<&'a BStr, E> { if i.is_empty() { - Ok((&[], i.as_bstr())) + rest.map(ByteSlice::as_bstr).parse_next(i) } else { - terminated(take_while(|c| c != b'\n'), opt(tag(b"\n")))(i).map(|(i, o)| (i, o.as_bstr())) + terminated(take_while(0.., |c| c != b'\n'), opt(b'\n')) + .map(ByteSlice::as_bstr) + .parse_next(i) } } - fn one<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(bytes: &'a [u8]) -> IResult<&[u8], LineRef<'a>, E> { - let (i, (old, new, signature, message_sep, message)) = context( - "<old-hexsha> <new-hexsha> <name> <<email>> <timestamp> <tz>\\t<message>", - tuple(( - context("<old-hexsha>", terminated(hex_hash, tag(b" "))), - context("<new-hexsha>", terminated(hex_hash, tag(b" "))), - context("<name> <<email>> <timestamp>", gix_actor::signature::decode), - opt(tag(b"\t")), - context("<optional message>", message), + fn one<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>( + bytes: &mut &'a [u8], + ) -> PResult<LineRef<'a>, E> { + ( + ( + terminated(hex_hash, b" ").context(StrContext::Expected("<old-hexsha>".into())), + terminated(hex_hash, b" ").context(StrContext::Expected("<new-hexsha>".into())), + gix_actor::signature::decode.context(StrContext::Expected("<name> <<email>> <timestamp>".into())), + ) + .context(StrContext::Expected( + "<old-hexsha> <new-hexsha> <name> <<email>> <timestamp> <tz>\\t<message>".into(), + )), + alt(( + preceded( + b'\t', + message.context(StrContext::Expected("<optional message>".into())), + ), + b'\n'.value(Default::default()), + eof.value(Default::default()), + fail.context(StrContext::Expected( + "log message must be separated from signature with whitespace".into(), + )), )), - )(bytes)?; - - if message_sep.is_none() { - if let Some(first) = message.first() { - if !first.is_ascii_whitespace() { - return Err(nom::Err::Error(E::add_context( - i, - "log message must be separated from signature with whitespace", - E::from_error_kind(i, nom::error::ErrorKind::MapRes), - ))); - } - } - } - - Ok(( - i, - LineRef { + ) + .map(|((old, new, signature), message)| LineRef { previous_oid: old, new_oid: new, signature, message, - }, - )) + }) + .parse_next(bytes) } #[cfg(test)] mod test { - use gix_actor::{Sign, Time}; + use gix_date::{time::Sign, Time}; use gix_object::bstr::ByteSlice; use super::*; @@ -185,13 +184,14 @@ pub mod decode { mod invalid { use gix_testtools::to_bstr_err; - use nom::error::VerboseError; + use winnow::{error::TreeError, prelude::*}; use super::one; #[test] fn completely_bogus_shows_error_with_context() { - let err = one::<VerboseError<&[u8]>>(b"definitely not a log entry") + let err = one::<TreeError<&[u8], _>> + .parse_peek(b"definitely not a log entry") .map_err(to_bstr_err) .expect_err("this should fail"); assert!(err.to_string().contains("<old-hexsha> <new-hexsha>")); @@ -200,12 +200,15 @@ pub mod decode { #[test] fn missing_whitespace_between_signature_and_message() { let line = "0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 one <foo@example.com> 1234567890 -0000message"; - let err = one::<VerboseError<&[u8]>>(line.as_bytes()) + let err = one::<TreeError<&[u8], _>> + .parse_peek(line.as_bytes()) .map_err(to_bstr_err) .expect_err("this should fail"); - assert!(err - .to_string() - .contains("log message must be separated from signature with whitespace")); + assert!( + err.to_string() + .contains("log message must be separated from signature with whitespace"), + "expected\n `log message must be separated from signature with whitespace`\nin\n```\n{err}\n```" + ); } } @@ -217,7 +220,10 @@ pub mod decode { let line_with_nl = with_newline(line_without_nl.clone()); for input in &[line_without_nl, line_with_nl] { assert_eq!( - one::<nom::error::Error<_>>(input).expect("successful parsing").1, + one::<winnow::error::InputError<_>> + .parse_peek(input) + .expect("successful parsing") + .1, LineRef { previous_oid: NULL_SHA1.as_bstr(), new_oid: NULL_SHA1.as_bstr(), @@ -225,8 +231,8 @@ pub mod decode { name: b"name".as_bstr(), email: b"foo@example.com".as_bstr(), time: Time { - seconds_since_unix_epoch: 1234567890, - offset_in_seconds: 0, + seconds: 1234567890, + offset: 0, sign: Sign::Minus } }, @@ -242,7 +248,9 @@ pub mod decode { let line_with_nl = with_newline(line_without_nl.clone()); for input in &[line_without_nl, line_with_nl] { - let (remaining, res) = one::<nom::error::Error<_>>(input).expect("successful parsing"); + let (remaining, res) = one::<winnow::error::InputError<_>> + .parse_peek(input) + .expect("successful parsing"); assert!(remaining.is_empty(), "all consuming even without trailing newline"); let actual = LineRef { previous_oid: b"a5828ae6b52137b913b978e16cd2334482eb4c1f".as_bstr(), @@ -251,8 +259,8 @@ pub mod decode { name: b"Sebastian Thiel".as_bstr(), email: b"foo@example.com".as_bstr(), time: Time { - seconds_since_unix_epoch: 1618030561, - offset_in_seconds: 28800, + seconds: 1618030561, + offset: 28800, sign: Sign::Plus, }, }, @@ -270,10 +278,14 @@ pub mod decode { #[test] fn two_lines_in_a_row_with_and_without_newline() { let lines = b"0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 one <foo@example.com> 1234567890 -0000\t\n0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 two <foo@example.com> 1234567890 -0000\thello"; - let (remainder, parsed) = one::<nom::error::Error<_>>(lines).expect("parse single line"); + let (remainder, parsed) = one::<winnow::error::InputError<_>> + .parse_peek(lines) + .expect("parse single line"); assert_eq!(parsed.message, b"".as_bstr(), "first message is empty"); - let (remainder, parsed) = one::<nom::error::Error<_>>(remainder).expect("parse single line"); + let (remainder, parsed) = one::<winnow::error::InputError<_>> + .parse_peek(remainder) + .expect("parse single line"); assert_eq!( parsed.message, b"hello".as_bstr(), diff --git a/vendor/gix-ref/src/store/file/loose/iter.rs b/vendor/gix-ref/src/store/file/loose/iter.rs index b4b46ccc4..cf110b6d5 100644 --- a/vendor/gix-ref/src/store/file/loose/iter.rs +++ b/vendor/gix-ref/src/store/file/loose/iter.rs @@ -13,10 +13,9 @@ pub(in crate::store_impl::file) struct SortedLoosePaths { } impl SortedLoosePaths { - pub fn at(path: impl AsRef<Path>, base: impl Into<PathBuf>, filename_prefix: Option<BString>) -> Self { - let path = path.as_ref(); + pub fn at(path: &Path, base: PathBuf, filename_prefix: Option<BString>) -> Self { SortedLoosePaths { - base: base.into(), + base, filename_prefix, file_walk: path.is_dir().then(|| { // serial iteration as we expect most refs in packed-refs anyway. @@ -89,7 +88,7 @@ impl file::Store { /// Return an iterator over all loose references that start with the given `prefix`. /// /// Otherwise it's similar to [`loose_iter()`][file::Store::loose_iter()]. - pub fn loose_iter_prefixed(&self, prefix: impl AsRef<Path>) -> std::io::Result<LooseThenPacked<'_, '_>> { + pub fn loose_iter_prefixed(&self, prefix: &Path) -> std::io::Result<LooseThenPacked<'_, '_>> { self.iter_prefixed_packed(prefix, None) } } diff --git a/vendor/gix-ref/src/store/file/loose/mod.rs b/vendor/gix-ref/src/store/file/loose/mod.rs index df51c389f..f3b12d0cc 100644 --- a/vendor/gix-ref/src/store/file/loose/mod.rs +++ b/vendor/gix-ref/src/store/file/loose/mod.rs @@ -33,9 +33,9 @@ mod init { /// Create a new instance at the given `git_dir`, which commonly is a standard git repository with a /// `refs/` subdirectory. /// The `object_hash` defines which kind of hash we should recognize. - pub fn at(git_dir: impl Into<PathBuf>, write_reflog: file::WriteReflog, object_hash: gix_hash::Kind) -> Self { + pub fn at(git_dir: PathBuf, write_reflog: file::WriteReflog, object_hash: gix_hash::Kind) -> Self { file::Store { - git_dir: git_dir.into(), + git_dir, common_dir: None, write_reflog, namespace: None, @@ -47,14 +47,14 @@ mod init { /// Like [`at()`][file::Store::at()], but for _linked_ work-trees which use `git_dir` as private ref store and `common_dir` for /// shared references. pub fn for_linked_worktree( - git_dir: impl Into<PathBuf>, - common_dir: impl Into<PathBuf>, + git_dir: PathBuf, + common_dir: PathBuf, write_reflog: file::WriteReflog, object_hash: gix_hash::Kind, ) -> Self { file::Store { - git_dir: git_dir.into(), - common_dir: Some(common_dir.into()), + git_dir, + common_dir: Some(common_dir), write_reflog, namespace: None, packed: gix_fs::SharedFileSnapshotMut::new().into(), diff --git a/vendor/gix-ref/src/store/file/loose/reference/decode.rs b/vendor/gix-ref/src/store/file/loose/reference/decode.rs index 9bf2f7c29..7ba898373 100644 --- a/vendor/gix-ref/src/store/file/loose/reference/decode.rs +++ b/vendor/gix-ref/src/store/file/loose/reference/decode.rs @@ -2,11 +2,10 @@ use std::convert::{TryFrom, TryInto}; use gix_hash::ObjectId; use gix_object::bstr::BString; -use nom::{ - bytes::complete::{tag, take_while}, - combinator::{map, opt}, - sequence::terminated, - IResult, +use winnow::{ + combinator::{opt, terminated}, + prelude::*, + token::take_while, }; use crate::{ @@ -39,15 +38,17 @@ impl TryFrom<MaybeUnsafeState> for Target { fn try_from(v: MaybeUnsafeState) -> Result<Self, Self::Error> { Ok(match v { MaybeUnsafeState::Id(id) => Target::Peeled(id), - MaybeUnsafeState::UnvalidatedPath(name) => Target::Symbolic(match gix_validate::refname(name.as_ref()) { - Ok(_) => FullName(name), - Err(err) => { - return Err(Error::RefnameValidation { - source: err, - path: name, - }) - } - }), + MaybeUnsafeState::UnvalidatedPath(name) => { + Target::Symbolic(match gix_validate::reference::name(name.as_ref()) { + Ok(_) => FullName(name), + Err(err) => { + return Err(Error::RefnameValidation { + source: err, + path: name, + }) + } + }) + } }) } } @@ -55,29 +56,26 @@ impl TryFrom<MaybeUnsafeState> for Target { impl Reference { /// Create a new reference of the given `parent` store with `relative_path` service as unique identifier /// at which the `path_contents` was read to obtain the refs value. - pub fn try_from_path(name: FullName, path_contents: &[u8]) -> Result<Self, Error> { + pub fn try_from_path(name: FullName, mut path_contents: &[u8]) -> Result<Self, Error> { Ok(Reference { name, - target: parse(path_contents) + target: parse(&mut path_contents) .map_err(|_| Error::Parse { content: path_contents.into(), })? - .1 .try_into()?, }) } } -fn parse(bytes: &[u8]) -> IResult<&[u8], MaybeUnsafeState> { - let is_space = |b: u8| b == b' '; - if let (path, Some(_ref_prefix)) = opt(terminated(tag("ref: "), take_while(is_space)))(bytes)? { - map( - terminated(take_while(|b| b != b'\r' && b != b'\n'), opt(newline)), - |path| MaybeUnsafeState::UnvalidatedPath(path.into()), - )(path) +fn parse(i: &mut &[u8]) -> PResult<MaybeUnsafeState> { + if let Some(_ref_prefix) = opt(terminated("ref: ", take_while(0.., b' '))).parse_next(i)? { + terminated(take_while(0.., |b| b != b'\r' && b != b'\n'), opt(newline)) + .map(|path| MaybeUnsafeState::UnvalidatedPath(path.into())) + .parse_next(i) } else { - map(terminated(hex_hash, opt(newline)), |hex| { - MaybeUnsafeState::Id(ObjectId::from_hex(hex).expect("prior validation")) - })(bytes) + terminated(hex_hash, opt(newline)) + .map(|hex| MaybeUnsafeState::Id(ObjectId::from_hex(hex).expect("prior validation"))) + .parse_next(i) } } diff --git a/vendor/gix-ref/src/store/file/loose/reflog.rs b/vendor/gix-ref/src/store/file/loose/reflog.rs index 88a8c2450..614dd59a9 100644 --- a/vendor/gix-ref/src/store/file/loose/reflog.rs +++ b/vendor/gix-ref/src/store/file/loose/reflog.rs @@ -134,7 +134,7 @@ pub mod create_or_update { Err(err) => { // TODO: when Kind::IsADirectory becomes stable, use that. if log_path.is_dir() { - gix_tempfile::remove_dir::empty_depth_first(&log_path) + gix_tempfile::remove_dir::empty_depth_first(log_path.clone()) .and_then(|_| options.open(&log_path)) .map(Some) .map_err(|_| Error::Append { diff --git a/vendor/gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs b/vendor/gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs index 16b9b1492..160e5a0ec 100644 --- a/vendor/gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs +++ b/vendor/gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs @@ -1,8 +1,9 @@ use std::{convert::TryInto, path::Path}; -use gix_actor::{Sign, Signature, Time}; +use gix_actor::Signature; +use gix_date::{time::Sign, Time}; use gix_object::bstr::ByteSlice; -use tempfile::TempDir; +use gix_testtools::tempfile::TempDir; use super::*; use crate::{file::WriteReflog, FullNameRef}; @@ -16,7 +17,7 @@ fn hex_to_id(hex: &str) -> gix_hash::ObjectId { fn empty_store(writemode: WriteReflog) -> Result<(TempDir, file::Store)> { let dir = TempDir::new()?; - let store = file::Store::at(dir.path(), writemode, gix_hash::Kind::Sha1); + let store = file::Store::at(dir.path().into(), writemode, gix_hash::Kind::Sha1); Ok((dir, store)) } @@ -54,8 +55,8 @@ fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append name: "committer".into(), email: "committer@example.com".into(), time: Time { - seconds_since_unix_epoch: 1234, - offset_in_seconds: 1800, + seconds: 1234, + offset: 1800, sign: Sign::Plus, }, }; diff --git a/vendor/gix-ref/src/store/file/overlay_iter.rs b/vendor/gix-ref/src/store/file/overlay_iter.rs index 795eda654..4188e86df 100644 --- a/vendor/gix-ref/src/store/file/overlay_iter.rs +++ b/vendor/gix-ref/src/store/file/overlay_iter.rs @@ -51,7 +51,7 @@ impl<'p, 's> LooseThenPacked<'p, 's> { fn loose_iter(&mut self, kind: IterKind) -> &mut Peekable<SortedLoosePaths> { match kind { IterKind::GitAndConsumeCommon => { - drop(self.iter_common_dir.as_mut().map(|iter| iter.next())); + drop(self.iter_common_dir.as_mut().map(Iterator::next)); &mut self.iter_git_dir } IterKind::Git => &mut self.iter_git_dir, @@ -198,7 +198,7 @@ impl<'s> Platform<'s> { /// As [`iter(…)`][file::Store::iter()], but filters by `prefix`, i.e. "refs/heads". /// /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/" - pub fn prefixed(&self, prefix: impl AsRef<Path>) -> std::io::Result<LooseThenPacked<'_, '_>> { + pub fn prefixed(&self, prefix: &Path) -> std::io::Result<LooseThenPacked<'_, '_>> { self.store .iter_prefixed_packed(prefix, self.packed.as_ref().map(|b| &***b)) } @@ -255,19 +255,19 @@ impl<'a> IterInfo<'a> { fn into_iter(self) -> Peekable<SortedLoosePaths> { match self { - IterInfo::Base { base } => SortedLoosePaths::at(base.join("refs"), base, None), + IterInfo::Base { base } => SortedLoosePaths::at(&base.join("refs"), base.into(), None), IterInfo::BaseAndIterRoot { base, iter_root, prefix: _, - } => SortedLoosePaths::at(iter_root, base, None), - IterInfo::PrefixAndBase { base, prefix } => SortedLoosePaths::at(base.join(prefix), base, None), + } => SortedLoosePaths::at(&iter_root, base.into(), None), + IterInfo::PrefixAndBase { base, prefix } => SortedLoosePaths::at(&base.join(prefix), base.into(), None), IterInfo::ComputedIterationRoot { iter_root, base, prefix: _, remainder, - } => SortedLoosePaths::at(iter_root, base, remainder), + } => SortedLoosePaths::at(&iter_root, base.into(), remainder), } .peekable() } @@ -299,7 +299,7 @@ impl<'a> IterInfo<'a> { .map(ToOwned::to_owned) .map(|p| { gix_path::try_into_bstr(PathBuf::from(p)) - .map(|p| p.into_owned()) + .map(std::borrow::Cow::into_owned) .map_err(|_| { std::io::Error::new(std::io::ErrorKind::InvalidInput, "prefix contains ill-formed UTF-8") }) @@ -352,12 +352,11 @@ impl file::Store { /// Please note that "refs/heads" or "refs\\heads" is equivalent to "refs/heads/" pub fn iter_prefixed_packed<'s, 'p>( &'s self, - prefix: impl AsRef<Path>, + prefix: &Path, packed: Option<&'p packed::Buffer>, ) -> std::io::Result<LooseThenPacked<'p, 's>> { match self.namespace.as_ref() { None => { - let prefix = prefix.as_ref(); let git_dir_info = IterInfo::from_prefix(self.git_dir(), prefix.into())?; let common_dir_info = self .common_dir() diff --git a/vendor/gix-ref/src/store/file/raw_ext.rs b/vendor/gix-ref/src/store/file/raw_ext.rs index b99bbbdd9..0aa598351 100644 --- a/vendor/gix-ref/src/store/file/raw_ext.rs +++ b/vendor/gix-ref/src/store/file/raw_ext.rs @@ -12,6 +12,12 @@ use crate::{ pub trait Sealed {} impl Sealed for crate::Reference {} +pub type FindObjectFn<'a> = dyn FnMut( + gix_hash::ObjectId, + &mut Vec<u8>, + ) -> Result<Option<(gix_object::Kind, &[u8])>, Box<dyn std::error::Error + Send + Sync>> + + 'a; + /// A trait to extend [Reference][crate::Reference] with functionality requiring a [file::Store]. pub trait ReferenceExt: Sealed { /// A step towards obtaining forward or reverse iterators on reference logs. @@ -21,17 +27,17 @@ pub trait ReferenceExt: Sealed { fn log_exists(&self, store: &file::Store) -> bool; /// For details, see [`Reference::peel_to_id_in_place()`]. - fn peel_to_id_in_place<E: std::error::Error + Send + Sync + 'static>( + fn peel_to_id_in_place( &mut self, store: &file::Store, - find: impl FnMut(gix_hash::ObjectId, &mut Vec<u8>) -> Result<Option<(gix_object::Kind, &[u8])>, E>, + find: &mut FindObjectFn<'_>, ) -> Result<ObjectId, peel::to_id::Error>; /// For details, see [`Reference::peel_to_id_in_place()`], with support for a known stable packed buffer. - fn peel_to_id_in_place_packed<E: std::error::Error + Send + Sync + 'static>( + fn peel_to_id_in_place_packed( &mut self, store: &file::Store, - find: impl FnMut(gix_hash::ObjectId, &mut Vec<u8>) -> Result<Option<(gix_object::Kind, &[u8])>, E>, + find: &mut FindObjectFn<'_>, packed: Option<&packed::Buffer>, ) -> Result<ObjectId, peel::to_id::Error>; @@ -66,10 +72,10 @@ impl ReferenceExt for Reference { .expect("infallible name conversion") } - fn peel_to_id_in_place<E: std::error::Error + Send + Sync + 'static>( + fn peel_to_id_in_place( &mut self, store: &file::Store, - find: impl FnMut(gix_hash::ObjectId, &mut Vec<u8>) -> Result<Option<(gix_object::Kind, &[u8])>, E>, + find: &mut FindObjectFn<'_>, ) -> Result<ObjectId, peel::to_id::Error> { let packed = store.assure_packed_refs_uptodate().map_err(|err| { peel::to_id::Error::Follow(file::find::existing::Error::Find(file::find::Error::PackedOpen(err))) @@ -77,10 +83,10 @@ impl ReferenceExt for Reference { self.peel_to_id_in_place_packed(store, find, packed.as_ref().map(|b| &***b)) } - fn peel_to_id_in_place_packed<E: std::error::Error + Send + Sync + 'static>( + fn peel_to_id_in_place_packed( &mut self, store: &file::Store, - mut find: impl FnMut(gix_hash::ObjectId, &mut Vec<u8>) -> Result<Option<(gix_object::Kind, &[u8])>, E>, + find: &mut FindObjectFn<'_>, packed: Option<&packed::Buffer>, ) -> Result<ObjectId, peel::to_id::Error> { match self.peeled { @@ -112,12 +118,10 @@ impl ReferenceExt for Reference { let mut buf = Vec::new(); let mut oid = self.target.try_id().expect("peeled ref").to_owned(); let peeled_id = loop { - let (kind, data) = find(oid, &mut buf) - .map_err(|err| Box::new(err) as Box<dyn std::error::Error + Send + Sync + 'static>)? - .ok_or_else(|| peel::to_id::Error::NotFound { - oid, - name: self.name.0.clone(), - })?; + let (kind, data) = find(oid, &mut buf)?.ok_or_else(|| peel::to_id::Error::NotFound { + oid, + name: self.name.0.clone(), + })?; match kind { gix_object::Kind::Tag => { oid = gix_object::TagRefIter::from_bytes(data).target_id().map_err(|_err| { diff --git a/vendor/gix-ref/src/store/file/transaction/commit.rs b/vendor/gix-ref/src/store/file/transaction/commit.rs index df32a1403..829e45ebb 100644 --- a/vendor/gix-ref/src/store/file/transaction/commit.rs +++ b/vendor/gix-ref/src/store/file/transaction/commit.rs @@ -50,7 +50,8 @@ impl<'s, 'p> Transaction<'s, 'p> { if update_reflog { let log_update = match new { Target::Symbolic(_) => { - // no reflog for symref changes, unless the ref is new and we can obtain a peeled id + // Special HACK: no reflog for symref changes as there is no OID involved which the reflog needs. + // Unless, the ref is new and we can obtain a peeled id // identified by the expectation of what could be there, as is the case when cloning. match expected { PreviousValue::ExistingMustMatch(Target::Peeled(oid)) => { @@ -61,6 +62,8 @@ impl<'s, 'p> Transaction<'s, 'p> { } Target::Peeled(new_oid) => { let previous = match expected { + // Here, this means that the ref already existed, and that it will receive (even transitively) + // the given value PreviousValue::MustExistAndMatch(Target::Peeled(oid)) => Some(oid.to_owned()), _ => None, } @@ -90,7 +93,7 @@ impl<'s, 'p> Transaction<'s, 'p> { continue; } if update_ref { - if let Some(Err(err)) = lock.map(|l| l.commit()) { + if let Some(Err(err)) = lock.map(gix_lock::Marker::commit) { // TODO: when Kind::IsADirectory becomes stable, use that. let err = if err.instance.resource_path().is_dir() { gix_tempfile::remove_dir::empty_depth_first(err.instance.resource_path()) diff --git a/vendor/gix-ref/src/store/file/transaction/mod.rs b/vendor/gix-ref/src/store/file/transaction/mod.rs index c285cd525..c3368c1b6 100644 --- a/vendor/gix-ref/src/store/file/transaction/mod.rs +++ b/vendor/gix-ref/src/store/file/transaction/mod.rs @@ -92,7 +92,7 @@ impl std::fmt::Debug for Transaction<'_, '_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("Transaction") .field("store", self.store) - .field("edits", &self.updates.as_ref().map(|u| u.len())) + .field("edits", &self.updates.as_ref().map(Vec::len)) .finish_non_exhaustive() } } diff --git a/vendor/gix-ref/src/store/file/transaction/prepare.rs b/vendor/gix-ref/src/store/file/transaction/prepare.rs index bfc5acabc..eb802f10f 100644 --- a/vendor/gix-ref/src/store/file/transaction/prepare.rs +++ b/vendor/gix-ref/src/store/file/transaction/prepare.rs @@ -205,15 +205,27 @@ impl<'s, 'p> Transaction<'s, 'p> { /// Rollbacks happen automatically on failure and they tend to be perfect. /// This method is idempotent. pub fn prepare( - mut self, + self, edits: impl IntoIterator<Item = RefEdit>, ref_files_lock_fail_mode: gix_lock::acquire::Fail, packed_refs_lock_fail_mode: gix_lock::acquire::Fail, ) -> Result<Self, Error> { + self.prepare_inner( + &mut edits.into_iter(), + ref_files_lock_fail_mode, + packed_refs_lock_fail_mode, + ) + } + + fn prepare_inner( + mut self, + edits: &mut dyn Iterator<Item = RefEdit>, + ref_files_lock_fail_mode: gix_lock::acquire::Fail, + packed_refs_lock_fail_mode: gix_lock::acquire::Fail, + ) -> Result<Self, Error> { assert!(self.updates.is_none(), "BUG: Must not call prepare(…) multiple times"); let store = self.store; let mut updates: Vec<_> = edits - .into_iter() .map(|update| Edit { update, lock: None, @@ -223,14 +235,14 @@ impl<'s, 'p> Transaction<'s, 'p> { .collect(); updates .pre_process( - |name| { + &mut |name| { let symbolic_refs_are_never_packed = None; store .find_existing_inner(name, symbolic_refs_are_never_packed) .map(|r| r.target) .ok() }, - |idx, update| Edit { + &mut |idx, update| Edit { update, lock: None, parent_index: Some(idx), @@ -326,10 +338,10 @@ impl<'s, 'p> Transaction<'s, 'p> { self.packed_transaction = Some(match &mut self.packed_refs { PackedRefs::DeletionsAndNonSymbolicUpdatesRemoveLooseSourceReference(f) | PackedRefs::DeletionsAndNonSymbolicUpdates(f) => { - transaction.prepare(edits_for_packed_transaction, f)? + transaction.prepare(&mut edits_for_packed_transaction.into_iter(), f)? } PackedRefs::DeletionsOnly => transaction - .prepare(edits_for_packed_transaction, &mut |_, _| { + .prepare(&mut edits_for_packed_transaction.into_iter(), &mut |_, _| { unreachable!("BUG: deletions never trigger object lookups") })?, }); @@ -342,7 +354,7 @@ impl<'s, 'p> Transaction<'s, 'p> { if let Err(err) = Self::lock_ref_and_apply_change( self.store, ref_files_lock_fail_mode, - self.packed_transaction.as_ref().and_then(|t| t.buffer()), + self.packed_transaction.as_ref().and_then(packed::Transaction::buffer), change, self.packed_transaction.is_some(), matches!( @@ -420,7 +432,7 @@ fn possibly_adjust_name_for_prefixes(name: &FullNameRef) -> Option<FullName> { .map_or(false, |cat| !cat.is_worktree_private()) .then_some(sn), } - .map(|n| n.to_owned()) + .map(ToOwned::to_owned) } None => Some(name.to_owned()), // allow (uncategorized/very special) refs to be packed } diff --git a/vendor/gix-ref/src/store/general/init.rs b/vendor/gix-ref/src/store/general/init.rs index 52c582a7a..6b8a80953 100644 --- a/vendor/gix-ref/src/store/general/init.rs +++ b/vendor/gix-ref/src/store/general/init.rs @@ -21,13 +21,8 @@ impl crate::Store { /// Create a new store at the given location, typically the `.git/` directory. /// /// `object_hash` defines the kind of hash to assume when dealing with refs. - pub fn at( - git_dir: impl Into<PathBuf>, - reflog_mode: WriteReflog, - object_hash: gix_hash::Kind, - ) -> Result<Self, Error> { + pub fn at(git_dir: PathBuf, reflog_mode: WriteReflog, object_hash: gix_hash::Kind) -> Result<Self, Error> { // for now, just try to read the directory - later we will do that naturally as we have to figure out if it's a ref-table or not. - let git_dir = git_dir.into(); std::fs::read_dir(&git_dir)?; Ok(crate::Store { inner: crate::store::State::Loose { diff --git a/vendor/gix-ref/src/store/packed/buffer.rs b/vendor/gix-ref/src/store/packed/buffer.rs index 6786e4a9f..333be9517 100644 --- a/vendor/gix-ref/src/store/packed/buffer.rs +++ b/vendor/gix-ref/src/store/packed/buffer.rs @@ -20,6 +20,7 @@ pub mod open { use std::path::PathBuf; use memmap2::Mmap; + use winnow::{prelude::*, stream::Offset}; use crate::store_impl::packed; @@ -29,8 +30,7 @@ pub mod open { /// /// In order to allow fast lookups and optimizations, the contents of the packed refs must be sorted. /// If that's not the case, they will be sorted on the fly with the data being written into a memory buffer. - pub fn open(path: impl Into<PathBuf>, use_memory_map_if_larger_than_bytes: u64) -> Result<Self, Error> { - let path = path.into(); + pub fn open(path: PathBuf, use_memory_map_if_larger_than_bytes: u64) -> Result<Self, Error> { let (backing, offset) = { let backing = if std::fs::metadata(&path)?.len() <= use_memory_map_if_larger_than_bytes { packed::Backing::InMemory(std::fs::read(&path)?) @@ -45,10 +45,12 @@ pub mod open { }; let (offset, sorted) = { - let data = backing.as_ref(); - if *data.first().unwrap_or(&b' ') == b'#' { - let (records, header) = packed::decode::header::<()>(data).map_err(|_| Error::HeaderParsing)?; - let offset = records.as_ptr() as usize - data.as_ptr() as usize; + let mut input = backing.as_ref(); + if *input.first().unwrap_or(&b' ') == b'#' { + let header = packed::decode::header::<()> + .parse_next(&mut input) + .map_err(|_| Error::HeaderParsing)?; + let offset = input.offset_from(&backing.as_ref()); (offset, header.sorted) } else { (0, false) diff --git a/vendor/gix-ref/src/store/packed/decode.rs b/vendor/gix-ref/src/store/packed/decode.rs index f8825459e..b4f8e8562 100644 --- a/vendor/gix-ref/src/store/packed/decode.rs +++ b/vendor/gix-ref/src/store/packed/decode.rs @@ -1,12 +1,11 @@ use std::convert::TryInto; use gix_object::bstr::{BStr, ByteSlice}; -use nom::{ - bytes::complete::{tag, take_while}, - combinator::{map, map_res, opt}, - error::{FromExternalError, ParseError}, - sequence::{delimited, preceded, terminated, tuple}, - IResult, +use winnow::{ + combinator::{delimited, opt, preceded, terminated}, + error::{FromExternalError, ParserError}, + prelude::*, + token::take_while, }; use crate::{ @@ -37,46 +36,47 @@ impl Default for Header { } } -fn until_newline<'a, E>(input: &'a [u8]) -> IResult<&'a [u8], &'a BStr, E> +fn until_newline<'a, E>(input: &mut &'a [u8]) -> PResult<&'a BStr, E> where - E: ParseError<&'a [u8]>, + E: ParserError<&'a [u8]>, { - map( - terminated(take_while(|b: u8| b != b'\r' && b != b'\n'), newline), - |not_newline| not_newline.as_bstr(), - )(input) + terminated(take_while(0.., |b: u8| b != b'\r' && b != b'\n'), newline) + .map(ByteSlice::as_bstr) + .parse_next(input) } -pub fn header<'a, E>(input: &'a [u8]) -> IResult<&'a [u8], Header, E> +pub fn header<'a, E>(input: &mut &'a [u8]) -> PResult<Header, E> where - E: ParseError<&'a [u8]>, + E: ParserError<&'a [u8]>, { - let (rest, traits) = preceded(tag(b"# pack-refs with: "), until_newline)(input)?; - - let mut peeled = Peeled::Unspecified; - let mut sorted = false; - for token in traits.as_bstr().split_str(b" ") { - if token == b"fully-peeled" { - peeled = Peeled::Fully; - } else if token == b"peeled" { - peeled = Peeled::Partial; - } else if token == b"sorted" { - sorted = true; - } - } - - Ok((rest, Header { peeled, sorted })) + preceded(b"# pack-refs with: ", until_newline) + .map(|traits| { + let mut peeled = Peeled::Unspecified; + let mut sorted = false; + for token in traits.as_bstr().split_str(b" ") { + if token == b"fully-peeled" { + peeled = Peeled::Fully; + } else if token == b"peeled" { + peeled = Peeled::Partial; + } else if token == b"sorted" { + sorted = true; + } + } + Header { peeled, sorted } + }) + .parse_next(input) } -pub fn reference<'a, E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], crate::name::Error>>( - input: &'a [u8], -) -> IResult<&'a [u8], packed::Reference<'a>, E> { - let (input, (target, name)) = tuple(( - terminated(hex_hash, tag(b" ")), - map_res(until_newline, TryInto::try_into), - ))(input)?; - let (rest, object) = opt(delimited(tag(b"^"), hex_hash, newline))(input)?; - Ok((rest, packed::Reference { name, target, object })) +pub fn reference<'a, E: ParserError<&'a [u8]> + FromExternalError<&'a [u8], crate::name::Error>>( + input: &mut &'a [u8], +) -> PResult<packed::Reference<'a>, E> { + ( + terminated(hex_hash, b" "), + until_newline.try_map(TryInto::try_into), + opt(delimited(b"^", hex_hash, newline)), + ) + .map(|(target, name, object)| packed::Reference { name, target, object }) + .parse_next(input) } #[cfg(test)] diff --git a/vendor/gix-ref/src/store/packed/decode/tests.rs b/vendor/gix-ref/src/store/packed/decode/tests.rs index 6c8f315c1..e864ee999 100644 --- a/vendor/gix-ref/src/store/packed/decode/tests.rs +++ b/vendor/gix-ref/src/store/packed/decode/tests.rs @@ -1,7 +1,7 @@ type Result = std::result::Result<(), Box<dyn std::error::Error>>; mod reference { - use nom::error::VerboseError; + use winnow::{error::TreeError, prelude::*}; use super::Result; use crate::{ @@ -16,9 +16,13 @@ mod reference { #[test] fn invalid() { - assert!(decode::reference::<()>(b"# what looks like a comment",).is_err()); + assert!(decode::reference::<()> + .parse_peek(b"# what looks like a comment",) + .is_err()); assert!( - decode::reference::<()>(b"^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\n",).is_err(), + decode::reference::<()> + .parse_peek(b"^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\n",) + .is_err(), "lonely peel" ); } @@ -27,7 +31,7 @@ mod reference { fn two_refs_in_a_row() -> Result { let input: &[u8] = b"d53c4b0f91f1b29769c9430f2d1c0bcab1170c75 refs/heads/alternates-after-packs-and-loose ^e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37\neaae9c1bc723209d793eb93f5587fa2604d5cd92 refs/heads/avoid-double-lookup\n"; - let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; + let (input, parsed) = decode::reference::<TreeError<_>>.parse_peek(input).unwrap(); assert_eq!( parsed, @@ -40,7 +44,7 @@ mod reference { assert_eq!(parsed.target(), hex_to_id("d53c4b0f91f1b29769c9430f2d1c0bcab1170c75")); assert_eq!(parsed.object(), hex_to_id("e9cdc958e7ce2290e2d7958cdb5aa9323ef35d37")); - let (input, parsed) = decode::reference::<VerboseError<_>>(input)?; + let (input, parsed) = decode::reference::<TreeError<_>>.parse_peek(input).unwrap(); assert!(input.is_empty(), "exhausted"); assert_eq!( parsed.name, @@ -55,6 +59,7 @@ mod reference { mod header { use gix_object::bstr::ByteSlice; use gix_testtools::to_bstr_err; + use winnow::prelude::*; use super::Result; use crate::store_impl::packed::{ @@ -65,12 +70,15 @@ mod header { #[test] fn invalid() { assert!( - decode::header::<()>(b"# some user comment").is_err(), + decode::header::<()>.parse_peek(b"# some user comment").is_err(), "something the user put there" ); - assert!(decode::header::<()>(b"# pack-refs: ").is_err(), "looks right but isn't"); assert!( - decode::header::<()>(b" # pack-refs with: ").is_err(), + decode::header::<()>.parse_peek(b"# pack-refs: ").is_err(), + "looks right but isn't" + ); + assert!( + decode::header::<()>.parse_peek(b" # pack-refs with: ").is_err(), "does not start with #" ); } @@ -78,7 +86,9 @@ mod header { #[test] fn valid_fully_peeled_stored() -> Result { let input: &[u8] = b"# pack-refs with: peeled fully-peeled sorted \nsomething else"; - let (rest, header) = decode::header::<nom::error::VerboseError<_>>(input).map_err(to_bstr_err)?; + let (rest, header) = decode::header::<winnow::error::TreeError<_, _>> + .parse_peek(input) + .map_err(to_bstr_err)?; assert_eq!(rest.as_bstr(), "something else", "remainder starts after newline"); assert_eq!( @@ -94,7 +104,7 @@ mod header { #[test] fn valid_peeled_unsorted() -> Result { let input: &[u8] = b"# pack-refs with: peeled\n"; - let (rest, header) = decode::header::<()>(input)?; + let (rest, header) = decode::header::<()>.parse_peek(input).unwrap(); assert!(rest.is_empty()); assert_eq!( @@ -110,7 +120,7 @@ mod header { #[test] fn valid_empty() -> Result { let input: &[u8] = b"# pack-refs with: \n"; - let (rest, header) = decode::header::<()>(input)?; + let (rest, header) = decode::header::<()>.parse_peek(input).unwrap(); assert!(rest.is_empty()); assert_eq!( diff --git a/vendor/gix-ref/src/store/packed/find.rs b/vendor/gix-ref/src/store/packed/find.rs index 8c1dcb5b2..002f76b0f 100644 --- a/vendor/gix-ref/src/store/packed/find.rs +++ b/vendor/gix-ref/src/store/packed/find.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; use gix_object::bstr::{BStr, BString, ByteSlice}; +use winnow::prelude::*; use crate::{store_impl::packed, FullNameRef, PartialNameRef}; @@ -40,11 +41,14 @@ impl packed::Buffer { pub(crate) fn try_find_full_name(&self, name: &FullNameRef) -> Result<Option<packed::Reference<'_>>, Error> { match self.binary_search_by(name.as_bstr()) { - Ok(line_start) => Ok(Some( - packed::decode::reference::<()>(&self.as_ref()[line_start..]) - .map_err(|_| Error::Parse)? - .1, - )), + Ok(line_start) => { + let mut input = &self.as_ref()[line_start..]; + Ok(Some( + packed::decode::reference::<()> + .parse_next(&mut input) + .map_err(|_| Error::Parse)?, + )) + } Err((parse_failure, _)) => { if parse_failure { Err(Error::Parse) @@ -90,9 +94,10 @@ impl packed::Buffer { let mut encountered_parse_failure = false; a.binary_search_by_key(&full_name.as_ref(), |b: &u8| { let ofs = b as *const u8 as usize - a.as_ptr() as usize; - let line = &a[search_start_of_record(ofs)..]; - packed::decode::reference::<()>(line) - .map(|(_rest, r)| r.name.as_bstr().as_bytes()) + let mut line = &a[search_start_of_record(ofs)..]; + packed::decode::reference::<()> + .parse_next(&mut line) + .map(|r| r.name.as_bstr().as_bytes()) .map_err(|err| { encountered_parse_failure = true; err diff --git a/vendor/gix-ref/src/store/packed/iter.rs b/vendor/gix-ref/src/store/packed/iter.rs index d9c49956b..03c54a5f8 100644 --- a/vendor/gix-ref/src/store/packed/iter.rs +++ b/vendor/gix-ref/src/store/packed/iter.rs @@ -1,4 +1,9 @@ use gix_object::bstr::{BString, ByteSlice}; +use winnow::{ + combinator::{preceded, rest}, + prelude::*, + stream::Stream as _, +}; use crate::store_impl::{packed, packed::decode}; @@ -14,8 +19,7 @@ impl packed::Buffer { } /// Return an iterator yielding only references matching the given prefix, ordered by reference name. - pub fn iter_prefixed(&self, prefix: impl Into<BString>) -> Result<packed::Iter<'_>, packed::iter::Error> { - let prefix = prefix.into(); + pub fn iter_prefixed(&self, prefix: BString) -> Result<packed::Iter<'_>, packed::iter::Error> { let first_record_with_prefix = self.binary_search_by(prefix.as_bstr()).unwrap_or_else(|(_, pos)| pos); packed::Iter::new_with_prefix(&self.as_ref()[first_record_with_prefix..], Some(prefix)) } @@ -29,9 +33,9 @@ impl<'a> Iterator for packed::Iter<'a> { return None; } - match decode::reference::<()>(self.cursor) { - Ok((rest, reference)) => { - self.cursor = rest; + let start = self.cursor.checkpoint(); + match decode::reference::<()>.parse_next(&mut self.cursor) { + Ok(reference) => { self.current_line += 1; if let Some(ref prefix) = self.prefix { if !reference.name.as_bstr().starts_with_str(prefix) { @@ -42,6 +46,7 @@ impl<'a> Iterator for packed::Iter<'a> { Some(Ok(reference)) } Err(_) => { + self.cursor.reset(start); let (failed_line, next_cursor) = self .cursor .find_byte(b'\n') @@ -82,9 +87,12 @@ impl<'a> packed::Iter<'a> { current_line: 1, }) } else if packed[0] == b'#' { - let (refs, _header) = decode::header::<()>(packed).map_err(|_| Error::Header { - invalid_first_line: packed.lines().next().unwrap_or(packed).into(), - })?; + let mut input = packed; + let refs = preceded(decode::header::<()>, rest) + .parse_next(&mut input) + .map_err(|_| Error::Header { + invalid_first_line: packed.lines().next().unwrap_or(packed).into(), + })?; Ok(packed::Iter { cursor: refs, prefix, diff --git a/vendor/gix-ref/src/store/packed/transaction.rs b/vendor/gix-ref/src/store/packed/transaction.rs index e487e218c..4c503d711 100644 --- a/vendor/gix-ref/src/store/packed/transaction.rs +++ b/vendor/gix-ref/src/store/packed/transaction.rs @@ -27,7 +27,7 @@ impl packed::Transaction { impl std::fmt::Debug for packed::Transaction { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("packed::Transaction") - .field("edits", &self.edits.as_ref().map(|e| e.len())) + .field("edits", &self.edits.as_ref().map(Vec::len)) .field("lock", &self.lock) .finish_non_exhaustive() } @@ -46,7 +46,7 @@ impl packed::Transaction { /// Prepare the transaction by checking all edits for applicability. pub fn prepare( mut self, - edits: impl IntoIterator<Item = RefEdit>, + edits: &mut dyn Iterator<Item = RefEdit>, find: &mut FindObjectFn<'_>, ) -> Result<Self, prepare::Error> { assert!(self.edits.is_none(), "BUG: cannot call prepare(…) more than once"); @@ -102,7 +102,7 @@ impl packed::Transaction { self.closed_lock = self .lock .take() - .map(|l| l.close()) + .map(gix_lock::File::close) .transpose() .map_err(prepare::Error::CloseLock)?; } else { @@ -189,7 +189,7 @@ impl packed::Transaction { } } -fn write_packed_ref(mut out: impl std::io::Write, pref: packed::Reference<'_>) -> std::io::Result<()> { +fn write_packed_ref(out: &mut dyn std::io::Write, pref: packed::Reference<'_>) -> std::io::Result<()> { write!(out, "{} ", pref.target)?; out.write_all(pref.name.as_bstr())?; out.write_all(b"\n")?; @@ -199,7 +199,7 @@ fn write_packed_ref(mut out: impl std::io::Write, pref: packed::Reference<'_>) - Ok(()) } -fn write_edit(mut out: impl std::io::Write, edit: &Edit, lines_written: &mut i32) -> std::io::Result<()> { +fn write_edit(out: &mut dyn std::io::Write, edit: &Edit, lines_written: &mut i32) -> std::io::Result<()> { match edit.inner.change { Change::Delete { .. } => {} Change::Update { diff --git a/vendor/gix-ref/src/transaction/ext.rs b/vendor/gix-ref/src/transaction/ext.rs index cb85d9d17..cd0c86401 100644 --- a/vendor/gix-ref/src/transaction/ext.rs +++ b/vendor/gix-ref/src/transaction/ext.rs @@ -18,8 +18,8 @@ where /// Note no action is performed if deref isn't specified. fn extend_with_splits_of_symbolic_refs( &mut self, - find: impl FnMut(&PartialNameRef) -> Option<Target>, - make_entry: impl FnMut(usize, RefEdit) -> T, + find: &mut dyn FnMut(&PartialNameRef) -> Option<Target>, + make_entry: &mut dyn FnMut(usize, RefEdit) -> T, ) -> Result<(), std::io::Error>; /// All processing steps in one and in the correct order. @@ -27,8 +27,8 @@ where /// Users call this to assure derefs are honored and duplicate checks are done. fn pre_process( &mut self, - find: impl FnMut(&PartialNameRef) -> Option<Target>, - make_entry: impl FnMut(usize, RefEdit) -> T, + find: &mut dyn FnMut(&PartialNameRef) -> Option<Target>, + make_entry: &mut dyn FnMut(usize, RefEdit) -> T, ) -> Result<(), std::io::Error> { self.extend_with_splits_of_symbolic_refs(find, make_entry)?; self.assure_one_name_has_one_edit().map_err(|name| { @@ -55,8 +55,8 @@ where fn extend_with_splits_of_symbolic_refs( &mut self, - mut find: impl FnMut(&PartialNameRef) -> Option<Target>, - mut make_entry: impl FnMut(usize, RefEdit) -> E, + find: &mut dyn FnMut(&PartialNameRef) -> Option<Target>, + make_entry: &mut dyn FnMut(usize, RefEdit) -> E, ) -> Result<(), std::io::Error> { let mut new_edits = Vec::new(); let mut first = 0; diff --git a/vendor/gix-ref/src/transaction/mod.rs b/vendor/gix-ref/src/transaction/mod.rs index 77ab7349d..47d050108 100644 --- a/vendor/gix-ref/src/transaction/mod.rs +++ b/vendor/gix-ref/src/transaction/mod.rs @@ -64,7 +64,7 @@ pub enum Change { /// The desired change to the reference log. log: LogChange, /// The expected value already present in the reference. - /// If a ref was existing previously it will be overwritten at `MustExistAndMatch(actual_value)` for use after + /// If a ref was existing previously this field will be overwritten with `MustExistAndMatch(actual_value)` for use after /// the transaction was committed successfully. expected: PreviousValue, /// The new state of the reference, either for updating an existing one or creating a new one. @@ -94,7 +94,6 @@ impl Change { /// Return references to values that are in common between all variants and denote the previous observed value. pub fn previous_value(&self) -> Option<crate::TargetRef<'_>> { match self { - // TODO: use or-patterns once MRV is larger than 1.52 (and this is supported) Change::Update { expected: PreviousValue::MustExistAndMatch(previous) | PreviousValue::ExistingMustMatch(previous), .. |