From 04494c65df05eef6b24acb68faae939a3d85f510 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 4 Sep 2023 09:00:15 +0200 Subject: [PATCH 1/4] switch the last crate (gix-package-tests) to edition 2021 --- gix-pack/tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gix-pack/tests/Cargo.toml b/gix-pack/tests/Cargo.toml index eac694538dc..1c2dc71a448 100644 --- a/gix-pack/tests/Cargo.toml +++ b/gix-pack/tests/Cargo.toml @@ -5,7 +5,7 @@ repository = "https://github.com/Byron/gitoxide" authors = ["Sebastian Thiel "] license = "MIT OR Apache-2.0" description = "Please use `gix-` instead ('git' -> 'gix')" -edition = "2018" +edition = "2021" rust-version = "1.65" [features] From ed327f6163f54756e58c20f86a563a97efb256ca Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 4 Sep 2023 14:53:12 +0200 Subject: [PATCH 2/4] chore!: update to the latest `prodash` It makes proper usage of `Progress` types easier and allows them to be used as `dyn` traits as well. --- Cargo.lock | 10 +-- Cargo.toml | 2 +- gitoxide-core/src/corpus/engine.rs | 18 +++--- gitoxide-core/src/corpus/trace.rs | 4 +- gitoxide-core/src/hours/core.rs | 33 +++------- gitoxide-core/src/hours/mod.rs | 4 +- gitoxide-core/src/hours/util.rs | 12 ++-- gitoxide-core/src/index/checkout.rs | 4 +- gitoxide-core/src/organize.rs | 6 +- gitoxide-core/src/pack/create.rs | 6 +- gitoxide-core/src/pack/explode.rs | 4 +- gitoxide-core/src/pack/index.rs | 4 +- gitoxide-core/src/pack/multi_index.rs | 10 ++- gitoxide-core/src/pack/receive.rs | 13 ++-- gitoxide-core/src/pack/verify.rs | 4 +- gitoxide-core/src/query/engine/command.rs | 4 +- gitoxide-core/src/query/engine/update.rs | 14 ++-- gitoxide-core/src/query/mod.rs | 2 +- gitoxide-core/src/repository/archive.rs | 4 +- .../attributes/validate_baseline.rs | 9 +-- gitoxide-core/src/repository/clone.rs | 4 +- gitoxide-core/src/repository/fetch.rs | 6 +- gitoxide-core/src/repository/odb.rs | 6 +- gitoxide-core/src/repository/revision/list.rs | 4 +- gitoxide-core/src/repository/verify.rs | 4 +- gix-features/Cargo.toml | 2 +- gix-features/src/progress.rs | 6 +- gix-odb/src/store_impls/dynamic/verify.rs | 4 +- gix-odb/src/store_impls/loose/verify.rs | 4 +- gix-pack/src/bundle/mod.rs | 4 +- gix-pack/src/bundle/write/mod.rs | 11 ++-- gix-pack/src/cache/delta/traverse/mod.rs | 5 +- gix-pack/src/cache/delta/traverse/resolve.rs | 40 +++++------- gix-pack/src/data/output/count/objects/mod.rs | 3 +- .../src/data/output/entry/iter_from_counts.rs | 4 +- gix-pack/src/index/traverse/mod.rs | 19 +++--- gix-pack/src/index/traverse/with_index.rs | 5 +- gix-pack/src/index/traverse/with_lookup.rs | 7 +- gix-pack/src/index/verify.rs | 6 +- gix-pack/src/index/write/encode.rs | 4 +- gix-pack/src/index/write/mod.rs | 4 +- gix-pack/src/multi_index/verify.rs | 10 +-- gix-pack/src/multi_index/write.rs | 8 +-- gix-protocol/src/fetch/delegate.rs | 16 ++--- gix-protocol/src/fetch_fn.rs | 8 +-- gix-protocol/src/handshake/function.rs | 6 +- gix-protocol/src/ls_refs.rs | 2 +- gix-worktree-state/src/checkout/chunk.rs | 64 ++++++------------- gix-worktree-state/src/checkout/function.rs | 30 +++------ gix/Cargo.toml | 2 +- gix/src/clone/checkout.rs | 2 +- gix/src/clone/fetch/mod.rs | 4 +- gix/src/lib.rs | 6 +- .../remote/connection/fetch/receive_pack.rs | 8 +-- gix/src/repository/worktree.rs | 2 +- src/shared.rs | 4 +- 56 files changed, 214 insertions(+), 277 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1663ffecdf3..dc26aa3b7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1137,7 +1137,7 @@ dependencies = [ "is-terminal", "once_cell", "owo-colors", - "prodash 25.0.2", + "prodash 26.0.0", "serde_derive", "tabled", "time", @@ -1237,7 +1237,7 @@ dependencies = [ "log", "once_cell", "parking_lot", - "prodash 25.0.2", + "prodash 26.0.0", "regex", "reqwest", "serde", @@ -1570,7 +1570,7 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash 25.0.2", + "prodash 26.0.0", "sha1", "sha1_smol", "thiserror", @@ -3503,9 +3503,9 @@ checksum = "9516b775656bc3e8985e19cd4b8c0c0de045095074e453d2c0a513b5f978392d" [[package]] name = "prodash" -version = "25.0.2" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d67eb4220992a4a052a4bb03cf776e493ecb1a3a36bab551804153d63486af7" +checksum = "2c85fe210cada0bbfc863bddeac230f5894e00d1617aa32d924302a36cf3e965" dependencies = [ "async-io", "bytesize", diff --git a/Cargo.toml b/Cargo.toml index baec8272c27..0abeb689d3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,7 +168,7 @@ gix = { version = "^0.53.0", path = "gix", default-features = false } time = "0.3.23" clap = { version = "4.1.1", features = ["derive", "cargo"] } -prodash = { version = "25.0.0", optional = true, default-features = false } +prodash = { version = "26.0.0", optional = true, default-features = false } is-terminal = { version = "0.4.0", optional = true } env_logger = { version = "0.10.0", default-features = false } crosstermion = { version = "0.11.0", optional = true, default-features = false } diff --git a/gitoxide-core/src/corpus/engine.rs b/gitoxide-core/src/corpus/engine.rs index e4f42abd516..5eb32197655 100644 --- a/gitoxide-core/src/corpus/engine.rs +++ b/gitoxide-core/src/corpus/engine.rs @@ -6,7 +6,7 @@ use std::{ use anyhow::{bail, Context}; use bytesize::ByteSize; -use gix::Progress; +use gix::{Count, NestedProgress, Progress}; use rusqlite::params; use super::db; @@ -55,7 +55,7 @@ impl Engine { pub fn refresh(&mut self, corpus_path: PathBuf) -> anyhow::Result<()> { let (corpus_path, corpus_id) = self.prepare_corpus_path(corpus_path)?; let repos = self.refresh_repos(&corpus_path, corpus_id)?; - self.state.progress.set_name("refresh repos"); + self.state.progress.set_name("refresh repos".into()); self.state.progress.info(format!( "Added or updated {} repositories under {corpus_path:?}", repos.len() @@ -87,7 +87,7 @@ impl Engine { repo_progress.init(Some(repos.len()), gix::progress::count("repos")); if task.execute_exclusive || threads == 1 || dry_run { if dry_run { - repo_progress.set_name("WOULD run"); + repo_progress.set_name("WOULD run".into()); for repo in &repos { repo_progress.info(format!( "{}", @@ -202,13 +202,11 @@ impl Engine { task.perform(&mut run, &repo.path, progress, Some(1), should_interrupt); }); if let Some(err) = run.error.as_deref() { - num_errors.fetch_add(1, Ordering::SeqCst); + num_errors.fetch_add(1, Ordering::Relaxed); progress.fail(err.to_owned()); } Self::update_run(con, run)?; - if let Some(counter) = counter.as_ref() { - counter.fetch_add(1, Ordering::SeqCst); - } + counter.fetch_add(1, Ordering::Relaxed); Ok(()) }, || (!gix::interrupt::is_triggered()).then(|| Duration::from_millis(100)), @@ -243,7 +241,7 @@ impl Engine { corpus_id: db::Id, sql_suffix: Option<&str>, ) -> anyhow::Result> { - self.state.progress.set_name("query db-repos"); + self.state.progress.set_name("query db-repos".into()); self.state.progress.init(None, gix::progress::count("repos")); Ok(self @@ -267,7 +265,7 @@ impl Engine { fn refresh_repos(&mut self, corpus_path: &Path, corpus_id: db::Id) -> anyhow::Result> { let start = Instant::now(); - self.state.progress.set_name("refresh"); + self.state.progress.set_name("refresh".into()); self.state.progress.init(None, gix::progress::count("repos")); let repos = std::thread::scope({ @@ -302,7 +300,7 @@ impl Engine { let find_progress = progress.add_child("find"); let write_db = scope.spawn(move || -> anyhow::Result> { - progress.set_name("write to DB"); + progress.set_name("write to DB".into()); progress.init(None, gix::progress::count("repos")); let mut out = Vec::new(); diff --git a/gitoxide-core/src/corpus/trace.rs b/gitoxide-core/src/corpus/trace.rs index c8dd7a78e40..d1dd42b4766 100644 --- a/gitoxide-core/src/corpus/trace.rs +++ b/gitoxide-core/src/corpus/trace.rs @@ -51,11 +51,11 @@ impl tracing_forest::printer::Formatter for StoreTreeToDb { use gix::Progress; if self.reverse_lines { for line in tree.lines().rev() { - progress.info(line); + progress.info(line.into()); } } else { for line in tree.lines() { - progress.info(line); + progress.info(line.into()); } } } diff --git a/gitoxide-core/src/hours/core.rs b/gitoxide-core/src/hours/core.rs index 9d312e20d61..9728f6b5ecd 100644 --- a/gitoxide-core/src/hours/core.rs +++ b/gitoxide-core/src/hours/core.rs @@ -67,11 +67,7 @@ pub fn estimate_hours( } } -type CommitChangeLineCounters = ( - Option>, - Option>, - Option>, -); +type CommitChangeLineCounters = (Arc, Arc, Arc); type SpawnResultWithReturnChannelAndWorkers<'scope> = ( crossbeam_channel::Sender, gix::hash::ObjectId)>>, @@ -95,7 +91,7 @@ pub fn spawn_tree_delta_threads<'scope>( let rx = rx.clone(); move || -> Result<_, anyhow::Error> { let mut out = Vec::new(); - let (commit_counter, change_counter, lines_counter) = stats_counters; + let (commits, changes, lines_count) = stats_counters; let mut attributes = line_stats .then(|| -> anyhow::Result<_> { repo.index_or_load_from_head().map_err(Into::into).and_then(|index| { @@ -115,9 +111,7 @@ pub fn spawn_tree_delta_threads<'scope>( .transpose()?; for chunk in rx { for (commit_idx, parent_commit, commit) in chunk { - if let Some(c) = commit_counter.as_ref() { - c.fetch_add(1, Ordering::SeqCst); - } + commits.fetch_add(1, Ordering::Relaxed); if gix::interrupt::is_triggered() { return Ok(out); } @@ -139,9 +133,7 @@ pub fn spawn_tree_delta_threads<'scope>( .track_rewrites(None) .for_each_to_obtain_tree(&to, |change| { use gix::object::tree::diff::change::Event::*; - if let Some(c) = change_counter.as_ref() { - c.fetch_add(1, Ordering::SeqCst); - } + changes.fetch_add(1, Ordering::Relaxed); match change.event { Rewrite { .. } => { unreachable!("we turned that off") @@ -149,13 +141,13 @@ pub fn spawn_tree_delta_threads<'scope>( Addition { entry_mode, id } => { if entry_mode.is_no_tree() { files.added += 1; - add_lines(line_stats, lines_counter.as_deref(), &mut lines, id); + add_lines(line_stats, &lines_count, &mut lines, id); } } Deletion { entry_mode, id } => { if entry_mode.is_no_tree() { files.removed += 1; - remove_lines(line_stats, lines_counter.as_deref(), &mut lines, id); + remove_lines(line_stats, &lines_count, &mut lines, id); } } Modification { @@ -168,16 +160,11 @@ pub fn spawn_tree_delta_threads<'scope>( (false, false) => {} (false, true) => { files.added += 1; - add_lines(line_stats, lines_counter.as_deref(), &mut lines, id); + add_lines(line_stats, &lines_count, &mut lines, id); } (true, false) => { files.removed += 1; - remove_lines( - line_stats, - lines_counter.as_deref(), - &mut lines, - previous_id, - ); + remove_lines(line_stats, &lines_count, &mut lines, previous_id); } (true, true) => { files.modified += 1; @@ -203,9 +190,7 @@ pub fn spawn_tree_delta_threads<'scope>( nl += counts.insertions as usize + counts.removals as usize; lines.added += counts.insertions as usize; lines.removed += counts.removals as usize; - if let Some(c) = lines_counter.as_ref() { - c.fetch_add(nl, Ordering::SeqCst); - } + lines_count.fetch_add(nl, Ordering::Relaxed); } } } diff --git a/gitoxide-core/src/hours/mod.rs b/gitoxide-core/src/hours/mod.rs index 26e577de1ab..2a814587349 100644 --- a/gitoxide-core/src/hours/mod.rs +++ b/gitoxide-core/src/hours/mod.rs @@ -5,7 +5,7 @@ use gix::{ actor, bstr::{BStr, ByteSlice}, prelude::*, - progress, Progress, + progress, Count, NestedProgress, Progress, }; /// Additional configuration for the hours estimation functionality. @@ -49,7 +49,7 @@ pub fn estimate( ) -> anyhow::Result<()> where W: io::Write, - P: Progress, + P: NestedProgress, { let repo = gix::discover(working_dir)?; let commit_id = repo.rev_parse_single(rev_spec)?.detach(); diff --git a/gitoxide-core/src/hours/util.rs b/gitoxide-core/src/hours/util.rs index f87be1767c1..55eff0cc06e 100644 --- a/gitoxide-core/src/hours/util.rs +++ b/gitoxide-core/src/hours/util.rs @@ -158,22 +158,18 @@ impl LineStats { /// An index able to address any commit pub type CommitIdx = u32; -pub fn add_lines(line_stats: bool, lines_counter: Option<&AtomicUsize>, lines: &mut LineStats, id: gix::Id<'_>) { +pub fn add_lines(line_stats: bool, lines_counter: &AtomicUsize, lines: &mut LineStats, id: gix::Id<'_>) { if let Some(Ok(blob)) = line_stats.then(|| id.object()) { let nl = blob.data.lines_with_terminator().count(); lines.added += nl; - if let Some(c) = lines_counter { - c.fetch_add(nl, Ordering::SeqCst); - } + lines_counter.fetch_add(nl, Ordering::Relaxed); } } -pub fn remove_lines(line_stats: bool, lines_counter: Option<&AtomicUsize>, lines: &mut LineStats, id: gix::Id<'_>) { +pub fn remove_lines(line_stats: bool, lines_counter: &AtomicUsize, lines: &mut LineStats, id: gix::Id<'_>) { if let Some(Ok(blob)) = line_stats.then(|| id.object()) { let nl = blob.data.lines_with_terminator().count(); lines.removed += nl; - if let Some(c) = lines_counter { - c.fetch_add(nl, Ordering::SeqCst); - } + lines_counter.fetch_add(nl, Ordering::Relaxed); } } diff --git a/gitoxide-core/src/index/checkout.rs b/gitoxide-core/src/index/checkout.rs index bdfaa3235f0..5ecb3688860 100644 --- a/gitoxide-core/src/index/checkout.rs +++ b/gitoxide-core/src/index/checkout.rs @@ -4,7 +4,7 @@ use std::{ }; use anyhow::bail; -use gix::{odb::FindExt, worktree::state::checkout, Progress}; +use gix::{odb::FindExt, worktree::state::checkout, NestedProgress, Progress}; use crate::{ index, @@ -16,7 +16,7 @@ pub fn checkout_exclusive( dest_directory: impl AsRef, repo: Option, mut err: impl std::io::Write, - mut progress: impl Progress, + mut progress: impl NestedProgress, should_interrupt: &AtomicBool, index::checkout_exclusive::Options { index: Options { object_hash, .. }, diff --git a/gitoxide-core/src/organize.rs b/gitoxide-core/src/organize.rs index 7a9809ef006..1feed705a18 100644 --- a/gitoxide-core/src/organize.rs +++ b/gitoxide-core/src/organize.rs @@ -3,7 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -use gix::{objs::bstr::ByteSlice, progress, Progress}; +use gix::{objs::bstr::ByteSlice, progress, NestedProgress, Progress}; #[derive(Default, Copy, Clone, Eq, PartialEq)] pub enum Mode { @@ -207,7 +207,7 @@ fn handle( } /// Find all working directories in the given `source_dir` and print them to `out` while providing `progress`. -pub fn discover( +pub fn discover( source_dir: impl AsRef, mut out: impl std::io::Write, mut progress: P, @@ -222,7 +222,7 @@ pub fn discover( Ok(()) } -pub fn run( +pub fn run( mode: Mode, source_dir: impl AsRef, destination: impl AsRef, diff --git a/gitoxide-core/src/pack/create.rs b/gitoxide-core/src/pack/create.rs index 4f8005de39d..7501e22a27f 100644 --- a/gitoxide-core/src/pack/create.rs +++ b/gitoxide-core/src/pack/create.rs @@ -9,7 +9,7 @@ use gix::{ odb::{pack, pack::FindExt}, parallel::InOrderIter, prelude::Finalize, - progress, traverse, Progress, + progress, traverse, Count, NestedProgress, Progress, }; use crate::OutputFormat; @@ -109,7 +109,7 @@ pub fn create( ) -> anyhow::Result<()> where W: std::io::Write, - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { let repo = gix::discover(repository_path)?.into_sync(); @@ -179,7 +179,7 @@ where Some(1) }; if nondeterministic_thread_count.is_some() && !may_use_multiple_threads { - progress.fail("Cannot use multi-threaded counting in tree-diff object expansion mode as it may yield way too many objects."); + progress.fail("Cannot use multi-threaded counting in tree-diff object expansion mode as it may yield way too many objects.".into()); } let (_, _, thread_count) = gix::parallel::optimize_chunk_size_and_thread_limit(50, None, thread_limit, None); let progress = progress::ThroughputOnDrop::new(progress); diff --git a/gitoxide-core/src/pack/explode.rs b/gitoxide-core/src/pack/explode.rs index 39583eb2a0c..5b00f29da0c 100644 --- a/gitoxide-core/src/pack/explode.rs +++ b/gitoxide-core/src/pack/explode.rs @@ -10,7 +10,7 @@ use gix::{ hash::ObjectId, object, objs, odb, odb::{loose, pack, Write}, - Progress, + NestedProgress, }; #[derive(Default, Clone, Eq, PartialEq, Debug)] @@ -137,7 +137,7 @@ pub fn pack_or_pack_index( pack_path: impl AsRef, object_path: Option>, check: SafetyCheck, - progress: impl Progress, + progress: impl NestedProgress, Context { thread_limit, delete_pack, diff --git a/gitoxide-core/src/pack/index.rs b/gitoxide-core/src/pack/index.rs index 15a84141a11..36a69258497 100644 --- a/gitoxide-core/src/pack/index.rs +++ b/gitoxide-core/src/pack/index.rs @@ -1,6 +1,6 @@ use std::{fs, io, path::PathBuf, str::FromStr, sync::atomic::AtomicBool}; -use gix::{odb::pack, Progress}; +use gix::{odb::pack, NestedProgress}; use crate::OutputFormat; @@ -77,7 +77,7 @@ pub fn from_pack

( ctx: Context<'static, impl io::Write>, ) -> anyhow::Result<()> where - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { use anyhow::Context; diff --git a/gitoxide-core/src/pack/multi_index.rs b/gitoxide-core/src/pack/multi_index.rs index da27f7f4730..b8e0603f480 100644 --- a/gitoxide-core/src/pack/multi_index.rs +++ b/gitoxide-core/src/pack/multi_index.rs @@ -1,13 +1,17 @@ use std::{io::BufWriter, path::PathBuf, sync::atomic::AtomicBool}; use anyhow::bail; -use gix::Progress; +use gix::NestedProgress; use crate::OutputFormat; pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; -pub fn verify(multi_index_path: PathBuf, progress: impl Progress, should_interrupt: &AtomicBool) -> anyhow::Result<()> { +pub fn verify( + multi_index_path: PathBuf, + progress: impl NestedProgress, + should_interrupt: &AtomicBool, +) -> anyhow::Result<()> { gix::odb::pack::multi_index::File::at(multi_index_path)?.verify_integrity_fast(progress, should_interrupt)?; Ok(()) } @@ -15,7 +19,7 @@ pub fn verify(multi_index_path: PathBuf, progress: impl Progress, should_interru pub fn create( index_paths: Vec, output_path: PathBuf, - progress: impl Progress, + progress: impl NestedProgress, should_interrupt: &AtomicBool, object_hash: gix::hash::Kind, ) -> anyhow::Result<()> { diff --git a/gitoxide-core/src/pack/receive.rs b/gitoxide-core/src/pack/receive.rs index 30574a66c66..9e4c009bb54 100644 --- a/gitoxide-core/src/pack/receive.rs +++ b/gitoxide-core/src/pack/receive.rs @@ -120,7 +120,7 @@ mod blocking_io { bstr::BString, protocol, protocol::{fetch::Response, handshake::Ref}, - Progress, + NestedProgress, }; use super::{receive_pack_blocking, CloneDelegate, Context}; @@ -130,7 +130,7 @@ mod blocking_io { fn receive_pack( &mut self, input: impl BufRead, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -156,7 +156,7 @@ mod blocking_io { ) -> anyhow::Result<()> where W: std::io::Write, - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { let transport = net::connect( @@ -188,6 +188,7 @@ mod blocking_io { #[cfg(feature = "blocking-client")] pub use blocking_io::receive; use gix::protocol::ls_refs; +use gix::NestedProgress; #[cfg(feature = "async-client")] mod async_io { @@ -211,7 +212,7 @@ mod async_io { async fn receive_pack( &mut self, input: impl AsyncBufRead + Unpin + 'async_trait, - progress: impl Progress, + progress: impl gix::NestedProgress, refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -236,7 +237,7 @@ mod async_io { ctx: Context, ) -> anyhow::Result<()> where - P: Progress + 'static, + P: gix::NestedProgress + 'static, W: io::Write + Send + 'static, { let transport = net::connect( @@ -367,7 +368,7 @@ fn receive_pack_blocking( mut refs_directory: Option, ctx: &mut Context, input: impl io::BufRead, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], ) -> io::Result<()> { let options = pack::bundle::write::Options { diff --git a/gitoxide-core/src/pack/verify.rs b/gitoxide-core/src/pack/verify.rs index 5a5db4edfdc..3b40a13858a 100644 --- a/gitoxide-core/src/pack/verify.rs +++ b/gitoxide-core/src/pack/verify.rs @@ -5,7 +5,7 @@ use bytesize::ByteSize; use gix::{ object, odb, odb::{pack, pack::index}, - Progress, + NestedProgress, }; pub use index::verify::Mode; pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=2; @@ -87,7 +87,7 @@ impl pack::cache::DecodeEntry for EitherCache { pub fn pack_or_pack_index( path: impl AsRef, - mut progress: impl Progress, + mut progress: impl NestedProgress, Context { mut out, mut err, diff --git a/gitoxide-core/src/query/engine/command.rs b/gitoxide-core/src/query/engine/command.rs index 6245d5472b1..5498af56046 100644 --- a/gitoxide-core/src/query/engine/command.rs +++ b/gitoxide-core/src/query/engine/command.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use anyhow::{bail, Context}; -use gix::{bstr::ByteSlice, prelude::ObjectIdExt, Progress}; +use gix::{bstr::ByteSlice, prelude::ObjectIdExt, Count, Progress}; use rusqlite::{params, OptionalExtension}; use crate::{ @@ -14,7 +14,7 @@ impl query::Engine { &self, cmd: Command, mut out: impl std::io::Write, - mut progress: impl gix::Progress, + mut progress: impl gix::NestedProgress, ) -> anyhow::Result<()> { match cmd { Command::TracePath { spec } => { diff --git a/gitoxide-core/src/query/engine/update.rs b/gitoxide-core/src/query/engine/update.rs index a9bcf389984..bae1a6d3daa 100644 --- a/gitoxide-core/src/query/engine/update.rs +++ b/gitoxide-core/src/query/engine/update.rs @@ -12,7 +12,7 @@ use gix::{ odb::FindExt, parallel::{InOrderIter, SequenceId}, prelude::ObjectIdExt, - Progress, + Count, Progress, }; use rusqlite::{params, Statement, Transaction}; @@ -21,7 +21,7 @@ use crate::query::Options; pub fn update( repo: &gix::Repository, con: &mut rusqlite::Connection, - progress: &mut impl gix::Progress, + progress: &mut impl gix::NestedProgress, mut err: impl std::io::Write, Options { object_cache_size_mb, @@ -37,28 +37,28 @@ pub fn update( p.init(None, progress::count("commits")); p }; - let stat_counter = stat_progress.counter().expect("shared counter available"); + let stat_counter = stat_progress.counter(); let mut db_progress = { let mut p = progress.add_child("db cache"); p.init(None, progress::count("events")); p }; - let commit_counter = db_progress.counter().expect("shared counter available"); + let commit_counter = db_progress.counter(); let change_progress = { let mut p = progress.add_child("find changes"); p.init(None, progress::count("modified files")); p }; - let change_counter = change_progress.counter().expect("shared counter available"); + let change_counter = change_progress.counter(); let lines_progress = { let mut p = progress.add_child("find changes"); p.init(None, progress::count("diff lines")); p }; - let lines_counter = lines_progress.counter().expect("shared counter available"); + let lines_counter = lines_progress.counter(); let mut traverse_progress = progress.add_child("traverse commit graph"); traverse_progress.init(None, progress::count("commits")); @@ -388,7 +388,7 @@ pub fn update( if saw_new_commits { db_progress.show_throughput(start); } else { - db_progress.info("up to date"); + db_progress.info("up to date".into()); } commits.extend(all_commits); diff --git a/gitoxide-core/src/query/mod.rs b/gitoxide-core/src/query/mod.rs index 9f1a376cef5..e1e2863825e 100644 --- a/gitoxide-core/src/query/mod.rs +++ b/gitoxide-core/src/query/mod.rs @@ -17,7 +17,7 @@ pub use engine::Command; pub fn prepare( repo_dir: &std::path::Path, - mut progress: impl gix::Progress, + mut progress: impl gix::NestedProgress, err: impl std::io::Write, opts: Options, ) -> anyhow::Result { diff --git a/gitoxide-core/src/repository/archive.rs b/gitoxide-core/src/repository/archive.rs index b27a14aab7a..7ef715638fa 100644 --- a/gitoxide-core/src/repository/archive.rs +++ b/gitoxide-core/src/repository/archive.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use anyhow::{anyhow, bail}; -use gix::{worktree::archive, Progress}; +use gix::{worktree::archive, NestedProgress, Progress}; pub struct Options { pub format: Option, @@ -14,7 +14,7 @@ pub fn stream( repo: gix::Repository, destination_path: &Path, rev_spec: Option<&str>, - mut progress: impl Progress, + mut progress: impl NestedProgress, Options { format, prefix, diff --git a/gitoxide-core/src/repository/attributes/validate_baseline.rs b/gitoxide-core/src/repository/attributes/validate_baseline.rs index 1702c81bcfa..f2c92f71a30 100644 --- a/gitoxide-core/src/repository/attributes/validate_baseline.rs +++ b/gitoxide-core/src/repository/attributes/validate_baseline.rs @@ -18,7 +18,7 @@ pub(crate) mod function { }; use anyhow::{anyhow, bail}; - use gix::{attrs::Assignment, bstr::BString, Progress}; + use gix::{attrs::Assignment, bstr::BString, Count, Progress}; use crate::{ repository::attributes::{query::attributes_cache, validate_baseline::Options}, @@ -28,7 +28,7 @@ pub(crate) mod function { pub fn validate_baseline( repo: gix::Repository, paths: Option + Send + 'static>, - mut progress: impl Progress + 'static, + mut progress: impl gix::NestedProgress + 'static, mut out: impl io::Write, mut err: impl io::Write, Options { @@ -249,10 +249,7 @@ pub(crate) mod function { "{}: Validation failed with {} mismatches out of {}", gix::path::realpath(repo.work_dir().unwrap_or(repo.git_dir()))?.display(), mismatches.len(), - progress - .counter() - .map(|a| a.load(Ordering::Relaxed)) - .unwrap_or_default() + progress.counter().load(Ordering::Relaxed) ); } } diff --git a/gitoxide-core/src/repository/clone.rs b/gitoxide-core/src/repository/clone.rs index 6fec5801335..96640c69537 100644 --- a/gitoxide-core/src/repository/clone.rs +++ b/gitoxide-core/src/repository/clone.rs @@ -14,7 +14,7 @@ pub(crate) mod function { use std::ffi::OsStr; use anyhow::{bail, Context}; - use gix::{bstr::BString, remote::fetch::Status, Progress}; + use gix::{bstr::BString, remote::fetch::Status, NestedProgress}; use super::Options; use crate::{repository::fetch::function::print_updates, OutputFormat}; @@ -35,7 +35,7 @@ pub(crate) mod function { }: Options, ) -> anyhow::Result<()> where - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { if format != OutputFormat::Human { diff --git a/gitoxide-core/src/repository/fetch.rs b/gitoxide-core/src/repository/fetch.rs index 35240a3b498..f20525da981 100644 --- a/gitoxide-core/src/repository/fetch.rs +++ b/gitoxide-core/src/repository/fetch.rs @@ -49,7 +49,7 @@ pub(crate) mod function { }: Options, ) -> anyhow::Result<()> where - P: gix::Progress, + P: gix::NestedProgress, P::SubProgress: 'static, { if format != OutputFormat::Human { @@ -134,7 +134,7 @@ pub(crate) mod function { mut progress: impl gix::Progress, ) -> anyhow::Result<()> { progress.init(Some(graph.len()), gix::progress::count("commits")); - progress.set_name("building graph"); + progress.set_name("building graph".into()); let mut map = gix::hashtable::HashMap::default(); let mut vg = layout::topo::layout::VisualGraph::new(Orientation::TopToBottom); @@ -168,7 +168,7 @@ pub(crate) mod function { } let start = std::time::Instant::now(); - progress.set_name("layout graph"); + progress.set_name("layout graph".into()); progress.info(format!("writing {path:?}…")); let mut svg = SVGWriter::new(); vg.do_it(false, false, false, &mut svg); diff --git a/gitoxide-core/src/repository/odb.rs b/gitoxide-core/src/repository/odb.rs index 1d3a08b6232..85c35618db2 100644 --- a/gitoxide-core/src/repository/odb.rs +++ b/gitoxide-core/src/repository/odb.rs @@ -69,7 +69,7 @@ pub fn statistics( } progress.init(None, gix::progress::count("objects")); - progress.set_name("counting"); + progress.set_name("counting".into()); let counter = progress.counter(); let start = std::time::Instant::now(); @@ -169,9 +169,7 @@ pub fn statistics( move |_| (repo.objects.clone().into_inner(), counter), |ids, (handle, counter)| { let ids = ids?; - if let Some(counter) = counter { - counter.fetch_add(ids.len(), std::sync::atomic::Ordering::SeqCst); - } + counter.fetch_add(ids.len(), std::sync::atomic::Ordering::Relaxed); let out = ids .into_iter() .map(|id| handle.header(id)) diff --git a/gitoxide-core/src/repository/revision/list.rs b/gitoxide-core/src/repository/revision/list.rs index 550d6ad9988..d1f80bcf5e5 100644 --- a/gitoxide-core/src/repository/revision/list.rs +++ b/gitoxide-core/src/repository/revision/list.rs @@ -65,7 +65,7 @@ pub(crate) mod function { Format::Text => None, }; progress.init(None, gix::progress::count("commits")); - progress.set_name("traverse"); + progress.set_name("traverse".into()); let start = std::time::Instant::now(); for commit in commits { @@ -116,7 +116,7 @@ pub(crate) mod function { progress.show_throughput(start); if let Some((mut vg, path, _)) = vg { let start = std::time::Instant::now(); - progress.set_name("layout graph"); + progress.set_name("layout graph".into()); progress.info(format!("writing {path:?}…")); let mut svg = SVGWriter::new(); vg.do_it(false, false, false, &mut svg); diff --git a/gitoxide-core/src/repository/verify.rs b/gitoxide-core/src/repository/verify.rs index 7e028fd2510..df5a74c5192 100644 --- a/gitoxide-core/src/repository/verify.rs +++ b/gitoxide-core/src/repository/verify.rs @@ -1,7 +1,5 @@ use std::sync::atomic::AtomicBool; -use gix::Progress; - use crate::{pack, OutputFormat}; /// A general purpose context for many operations provided here @@ -21,7 +19,7 @@ pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; pub fn integrity( repo: gix::Repository, mut out: impl std::io::Write, - progress: impl Progress, + progress: impl gix::NestedProgress, should_interrupt: &AtomicBool, Context { output_statistics, diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index df27af35d4f..337eaec3ece 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -129,7 +129,7 @@ crc32fast = { version = "1.2.1", optional = true } sha1 = { version = "0.10.0", optional = true } # progress -prodash = { version = "25.0.0", optional = true, default-features = false } +prodash = { version = "26.0.0", optional = true, default-features = false } bytesize = { version = "1.0.1", optional = true } # pipe diff --git a/gix-features/src/progress.rs b/gix-features/src/progress.rs index 6a90d84227d..1f13fdab89d 100644 --- a/gix-features/src/progress.rs +++ b/gix-features/src/progress.rs @@ -7,7 +7,7 @@ pub use prodash::{ self, messages::MessageLevel, progress::{Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN}, - unit, Progress, RawProgress, Unit, + unit, Count, NestedProgress, Progress, Unit, }; /// A stub for the portions of the `bytesize` crate that we use internally in `gitoxide`. #[cfg(not(feature = "progress-unit-bytes"))] @@ -77,7 +77,7 @@ pub fn steps() -> Option { Some(unit::dynamic(unit::Range::new("steps"))) } -/// A structure passing every [`read`][std::io::Read::read()] call through to the contained Progress instance using [`inc_by(bytes_read)`][Progress::inc_by()]. +/// A structure passing every [`read`](std::io::Read::read()) call through to the contained Progress instance using [`inc_by(bytes_read)`](Count::inc_by()). pub struct Read { /// The implementor of [`std::io::Read`] to which progress is added pub inner: T, @@ -111,7 +111,7 @@ where } } -/// A structure passing every [`write`][std::io::Write::write()] call through to the contained Progress instance using [`inc_by(bytes_written)`][Progress::inc_by()]. +/// A structure passing every [`write`][std::io::Write::write()] call through to the contained Progress instance using [`inc_by(bytes_written)`](Count::inc_by()). /// /// This is particularly useful if the final size of the bytes to write is known or can be estimated precisely enough. pub struct Write { diff --git a/gix-odb/src/store_impls/dynamic/verify.rs b/gix-odb/src/store_impls/dynamic/verify.rs index d8039cbebcc..b17f102459b 100644 --- a/gix-odb/src/store_impls/dynamic/verify.rs +++ b/gix-odb/src/store_impls/dynamic/verify.rs @@ -4,7 +4,7 @@ use std::{ time::Instant, }; -use gix_features::progress::{MessageLevel, Progress}; +use gix_features::progress::{MessageLevel, NestedProgress, Progress}; use crate::{ pack, @@ -118,7 +118,7 @@ impl super::Store { options: integrity::Options, ) -> Result, integrity::Error> where - P: Progress, + P: NestedProgress, C: pack::cache::DecodeEntry, F: Fn() -> C + Send + Clone, { diff --git a/gix-odb/src/store_impls/loose/verify.rs b/gix-odb/src/store_impls/loose/verify.rs index 8ffbb7105d6..4ba7f13ee1e 100644 --- a/gix-odb/src/store_impls/loose/verify.rs +++ b/gix-odb/src/store_impls/loose/verify.rs @@ -3,7 +3,7 @@ use std::{ time::Instant, }; -use gix_features::progress::Progress; +use gix_features::progress::{Count, NestedProgress, Progress}; use crate::{loose::Store, Write}; @@ -61,7 +61,7 @@ impl Store { /// Check all loose objects for their integrity checking their hash matches the actual data and by decoding them fully. pub fn verify_integrity( &self, - mut progress: impl Progress, + mut progress: impl NestedProgress, should_interrupt: &AtomicBool, ) -> Result { let mut buf = Vec::new(); diff --git a/gix-pack/src/bundle/mod.rs b/gix-pack/src/bundle/mod.rs index 076b355d984..c7ba4312320 100644 --- a/gix-pack/src/bundle/mod.rs +++ b/gix-pack/src/bundle/mod.rs @@ -10,7 +10,7 @@ pub mod write; pub mod verify { use std::sync::atomic::AtomicBool; - use gix_features::progress::Progress; + use gix_features::progress::NestedProgress; /// pub mod integrity { @@ -37,7 +37,7 @@ pub mod verify { options: crate::index::verify::integrity::Options, ) -> Result, crate::index::traverse::Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, F: Fn() -> C + Send + Clone, { diff --git a/gix-pack/src/bundle/write/mod.rs b/gix-pack/src/bundle/write/mod.rs index fa6e0402ffa..b881379e01f 100644 --- a/gix-pack/src/bundle/write/mod.rs +++ b/gix-pack/src/bundle/write/mod.rs @@ -6,7 +6,10 @@ use std::{ sync::{atomic::AtomicBool, Arc}, }; -use gix_features::{interrupt, progress, progress::Progress}; +use gix_features::{ + interrupt, progress, + progress::{NestedProgress, Progress}, +}; use gix_tempfile::{AutoRemove, ContainingDirectory}; use crate::data; @@ -65,7 +68,7 @@ impl crate::Bundle { pub fn write_to_directory( pack: impl io::BufRead, directory: Option>, - mut progress: impl Progress, + mut progress: impl NestedProgress, should_interrupt: &AtomicBool, thin_pack_base_object_lookup_fn: Option, options: Options, @@ -181,7 +184,7 @@ impl crate::Bundle { options: Options, ) -> Result where - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { let _span = gix_features::trace::coarse!("gix_pack::Bundle::write_to_directory_eagerly()"); @@ -270,7 +273,7 @@ impl crate::Bundle { fn inner_write( directory: Option>, - mut progress: impl Progress, + mut progress: impl NestedProgress, Options { thread_limit, iteration_mode: _, diff --git a/gix-pack/src/cache/delta/traverse/mod.rs b/gix-pack/src/cache/delta/traverse/mod.rs index e933af838b3..d585dff1a72 100644 --- a/gix-pack/src/cache/delta/traverse/mod.rs +++ b/gix-pack/src/cache/delta/traverse/mod.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; +use gix_features::progress::NestedProgress; use gix_features::{ parallel::in_parallel_with_slice, progress::{self, Progress}, @@ -116,9 +117,9 @@ where where F: for<'r> Fn(EntryRange, &'r R) -> Option<&'r [u8]> + Send + Clone, R: Send + Sync, - P1: Progress, + P1: NestedProgress, P2: Progress, - MBFN: FnMut(&mut T, &::SubProgress, Context<'_>) -> Result<(), E> + Send + Clone, + MBFN: FnMut(&mut T, &::SubProgress, Context<'_>) -> Result<(), E> + Send + Clone, E: std::error::Error + Send + Sync + 'static, { self.set_pack_entries_end_and_resolve_ref_offsets(pack_entries_end)?; diff --git a/gix-pack/src/cache/delta/traverse/resolve.rs b/gix-pack/src/cache/delta/traverse/resolve.rs index f5a14efb924..77b23f94ea5 100644 --- a/gix-pack/src/cache/delta/traverse/resolve.rs +++ b/gix-pack/src/cache/delta/traverse/resolve.rs @@ -28,8 +28,8 @@ pub(crate) struct State { #[allow(clippy::too_many_arguments)] pub(crate) fn deltas( - object_counter: Option, - size_counter: Option, + objects: gix_features::progress::StepShared, + size: gix_features::progress::StepShared, node: &mut Item, State { delta_bytes, @@ -104,10 +104,8 @@ where }, ) .map_err(|err| Box::new(err) as Box)?; - object_counter.as_ref().map(|c| c.fetch_add(1, Ordering::SeqCst)); - size_counter - .as_ref() - .map(|c| c.fetch_add(base_bytes.len(), Ordering::SeqCst)); + objects.fetch_add(1, Ordering::Relaxed); + size.fetch_add(base_bytes.len(), Ordering::Relaxed); } for mut child in base.into_child_iter() { @@ -146,10 +144,8 @@ where }, ) .map_err(|err| Box::new(err) as Box)?; - object_counter.as_ref().map(|c| c.fetch_add(1, Ordering::SeqCst)); - size_counter - .as_ref() - .map(|c| c.fetch_add(base_bytes.len(), Ordering::SeqCst)); + objects.fetch_add(1, Ordering::Relaxed); + size.fetch_add(base_bytes.len(), Ordering::Relaxed); } } @@ -169,8 +165,8 @@ where return deltas_mt( initial_threads, decompressed_bytes_by_pack_offset, - object_counter, - size_counter, + objects, + size, progress, nodes, resolve.clone(), @@ -194,8 +190,8 @@ where pub(crate) fn deltas_mt( mut threads_to_create: isize, decompressed_bytes_by_pack_offset: BTreeMap)>, - object_counter: Option, - size_counter: Option, + objects: gix_features::progress::StepShared, + size: gix_features::progress::StepShared, progress: &P, nodes: Vec<(u16, Node<'_, T>)>, resolve: F, @@ -230,8 +226,8 @@ where let decompressed_bytes_by_pack_offset = &decompressed_bytes_by_pack_offset; let resolve = resolve.clone(); let mut modify_base = modify_base.clone(); - let object_counter = object_counter.as_ref(); - let size_counter = size_counter.as_ref(); + let objects = &objects; + let size = &size; move || -> Result<(), Error> { let mut fully_resolved_delta_bytes = Vec::new(); @@ -282,10 +278,8 @@ where }, ) .map_err(|err| Box::new(err) as Box)?; - object_counter.as_ref().map(|c| c.fetch_add(1, Ordering::SeqCst)); - size_counter - .as_ref() - .map(|c| c.fetch_add(base_bytes.len(), Ordering::SeqCst)); + objects.fetch_add(1, Ordering::Relaxed); + size.fetch_add(base_bytes.len(), Ordering::Relaxed); } for mut child in base.into_child_iter() { @@ -330,10 +324,8 @@ where }, ) .map_err(|err| Box::new(err) as Box)?; - object_counter.as_ref().map(|c| c.fetch_add(1, Ordering::SeqCst)); - size_counter - .as_ref() - .map(|c| c.fetch_add(base_bytes.len(), Ordering::SeqCst)); + objects.fetch_add(1, Ordering::Relaxed); + size.fetch_add(base_bytes.len(), Ordering::Relaxed); } } } diff --git a/gix-pack/src/data/output/count/objects/mod.rs b/gix-pack/src/data/output/count/objects/mod.rs index 1559fa894e9..3f9a28bd162 100644 --- a/gix-pack/src/data/output/count/objects/mod.rs +++ b/gix-pack/src/data/output/count/objects/mod.rs @@ -3,6 +3,7 @@ use std::{ sync::{atomic::AtomicBool, Arc}, }; +use gix_features::progress::NestedProgress; use gix_features::{parallel, progress::Progress}; use gix_hash::ObjectId; @@ -38,7 +39,7 @@ pub type Result = std::result::Result<(Vec, Outcome), Err pub fn objects( db: Find, objects_ids: Iter, - progress: impl Progress, + progress: impl NestedProgress, should_interrupt: &AtomicBool, Options { thread_limit, diff --git a/gix-pack/src/data/output/entry/iter_from_counts.rs b/gix-pack/src/data/output/entry/iter_from_counts.rs index 1ac426f13bd..c8cb7d39e82 100644 --- a/gix-pack/src/data/output/entry/iter_from_counts.rs +++ b/gix-pack/src/data/output/entry/iter_from_counts.rs @@ -1,6 +1,8 @@ pub(crate) mod function { use std::{cmp::Ordering, sync::Arc}; + use gix_features::progress::prodash::Count; + use gix_features::progress::NestedProgress; use gix_features::{parallel, parallel::SequenceId, progress::Progress}; use super::{reduce, util, Error, Mode, Options, Outcome, ProgressId}; @@ -38,7 +40,7 @@ pub(crate) mod function { pub fn iter_from_counts( mut counts: Vec, db: Find, - mut progress: impl Progress + 'static, + mut progress: impl NestedProgress + 'static, Options { version, mode, diff --git a/gix-pack/src/index/traverse/mod.rs b/gix-pack/src/index/traverse/mod.rs index ee9b6bc3dc2..a83da4a70e0 100644 --- a/gix-pack/src/index/traverse/mod.rs +++ b/gix-pack/src/index/traverse/mod.rs @@ -1,10 +1,6 @@ use std::sync::atomic::AtomicBool; -use gix_features::{ - parallel, - progress::{Progress, RawProgress}, - zlib, -}; +use gix_features::{parallel, progress::Progress, zlib}; use crate::index; @@ -17,6 +13,7 @@ use reduce::Reducer; mod error; pub use error::Error; +use gix_features::progress::NestedProgress; mod types; pub use types::{Algorithm, ProgressId, SafetyCheck, Statistics}; @@ -92,10 +89,10 @@ impl index::File { }: Options, ) -> Result, Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, E: std::error::Error + Send + Sync + 'static, - Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn RawProgress) -> Result<(), E> + Send + Clone, + Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn Progress) -> Result<(), E> + Send + Clone, F: Fn() -> C + Send + Clone, { match traversal { @@ -157,9 +154,9 @@ impl index::File { cache: &mut C, buf: &mut Vec, inflate: &mut zlib::Inflate, - progress: &mut dyn RawProgress, + progress: &mut dyn Progress, index_entry: &index::Entry, - processor: &mut impl FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn RawProgress) -> Result<(), E>, + processor: &mut impl FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn Progress) -> Result<(), E>, ) -> Result> where C: crate::cache::DecodeEntry, @@ -208,8 +205,8 @@ fn process_entry( decompressed: &[u8], index_entry: &index::Entry, pack_entry_crc32: impl FnOnce() -> u32, - progress: &dyn RawProgress, - processor: &mut impl FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn RawProgress) -> Result<(), E>, + progress: &dyn Progress, + processor: &mut impl FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn Progress) -> Result<(), E>, ) -> Result<(), Error> where E: std::error::Error + Send + Sync + 'static, diff --git a/gix-pack/src/index/traverse/with_index.rs b/gix-pack/src/index/traverse/with_index.rs index 884277c9dfe..75f9b912831 100644 --- a/gix-pack/src/index/traverse/with_index.rs +++ b/gix-pack/src/index/traverse/with_index.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; +use gix_features::progress::NestedProgress; use gix_features::{parallel, progress::Progress}; use super::Error; @@ -65,8 +66,8 @@ impl index::File { Options { check, thread_limit }: Options, ) -> Result, Error> where - P: Progress, - Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn gix_features::progress::RawProgress) -> Result<(), E> + P: NestedProgress, + Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn gix_features::progress::Progress) -> Result<(), E> + Send + Clone, E: std::error::Error + Send + Sync + 'static, diff --git a/gix-pack/src/index/traverse/with_lookup.rs b/gix-pack/src/index/traverse/with_lookup.rs index 44f421323ac..9aae8a91b65 100644 --- a/gix-pack/src/index/traverse/with_lookup.rs +++ b/gix-pack/src/index/traverse/with_lookup.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; +use gix_features::progress::{Count, NestedProgress}; use gix_features::{ parallel::{self, in_parallel_if}, progress::{self, Progress}, @@ -79,12 +80,10 @@ impl index::File { }: Options, ) -> Result, Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, E: std::error::Error + Send + Sync + 'static, - Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn gix_features::progress::RawProgress) -> Result<(), E> - + Send - + Clone, + Processor: FnMut(gix_object::Kind, &[u8], &index::Entry, &dyn Progress) -> Result<(), E> + Send + Clone, F: Fn() -> C + Send + Clone, { let (verify_result, traversal_result) = parallel::join( diff --git a/gix-pack/src/index/verify.rs b/gix-pack/src/index/verify.rs index 3232329a3f9..de08c327722 100644 --- a/gix-pack/src/index/verify.rs +++ b/gix-pack/src/index/verify.rs @@ -1,6 +1,6 @@ use std::sync::atomic::AtomicBool; -use gix_features::progress::Progress; +use gix_features::progress::{NestedProgress, Progress}; use gix_object::{bstr::ByteSlice, WriteTo}; use crate::index; @@ -175,7 +175,7 @@ impl index::File { should_interrupt: &AtomicBool, ) -> Result, index::traverse::Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, F: Fn() -> C + Send + Clone, { @@ -239,7 +239,7 @@ impl index::File { object_kind: gix_object::Kind, buf: &[u8], index_entry: &index::Entry, - progress: &dyn gix_features::progress::RawProgress, + progress: &dyn gix_features::progress::Progress, ) -> Result<(), integrity::Error> { if let Mode::HashCrc32Decode | Mode::HashCrc32DecodeEncode = verify_mode { use gix_object::Kind::*; diff --git a/gix-pack/src/index/write/encode.rs b/gix-pack/src/index/write/encode.rs index f1195875c41..35e957f16f2 100644 --- a/gix-pack/src/index/write/encode.rs +++ b/gix-pack/src/index/write/encode.rs @@ -5,7 +5,7 @@ pub(crate) const HIGH_BIT: u32 = 0x8000_0000; use gix_features::{ hash, - progress::{self, Progress}, + progress::{self, NestedProgress}, }; use crate::index::{util::Count, V2_SIGNATURE}; @@ -15,7 +15,7 @@ pub(crate) fn write_to( entries_sorted_by_oid: Vec>, pack_hash: &gix_hash::ObjectId, kind: crate::index::Version, - mut progress: impl Progress, + mut progress: impl NestedProgress, ) -> io::Result { use io::Write; assert_eq!(kind, crate::index::Version::V2, "Can only write V2 packs right now"); diff --git a/gix-pack/src/index/write/mod.rs b/gix-pack/src/index/write/mod.rs index 72a076a851b..1626310aff2 100644 --- a/gix-pack/src/index/write/mod.rs +++ b/gix-pack/src/index/write/mod.rs @@ -1,7 +1,7 @@ use std::{convert::TryInto, io, sync::atomic::AtomicBool}; pub use error::Error; -use gix_features::progress::{self, Progress}; +use gix_features::progress::{self, Count, NestedProgress, Progress}; use crate::cache::delta::{traverse, Tree}; @@ -98,7 +98,7 @@ impl crate::index::File { F: FnOnce() -> io::Result<(F2, R)>, R: Send + Sync, F2: for<'r> Fn(crate::data::EntryRange, &'r R) -> Option<&'r [u8]> + Send + Clone, - P: Progress, + P: NestedProgress, { if version != crate::index::Version::default() { return Err(Error::Unsupported(version)); diff --git a/gix-pack/src/multi_index/verify.rs b/gix-pack/src/multi_index/verify.rs index 856a48501d3..ab84a76e940 100644 --- a/gix-pack/src/multi_index/verify.rs +++ b/gix-pack/src/multi_index/verify.rs @@ -1,6 +1,6 @@ use std::{cmp::Ordering, sync::atomic::AtomicBool, time::Instant}; -use gix_features::progress::Progress; +use gix_features::progress::{Count, NestedProgress, Progress}; use crate::{index, multi_index::File}; @@ -102,7 +102,7 @@ impl File { should_interrupt: &AtomicBool, ) -> Result<(gix_hash::ObjectId, P), integrity::Error> where - P: Progress, + P: NestedProgress, { self.verify_integrity_inner( progress, @@ -127,7 +127,7 @@ impl File { options: index::verify::integrity::Options, ) -> Result, index::traverse::Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, F: Fn() -> C + Send + Clone, { @@ -142,7 +142,7 @@ impl File { options: index::verify::integrity::Options, ) -> Result, index::traverse::Error> where - P: Progress, + P: NestedProgress, C: crate::cache::DecodeEntry, F: Fn() -> C + Send + Clone, { @@ -325,7 +325,7 @@ impl File { "BUG: our slicing should allow to visit all objects" ); - progress.set_name("Validating multi-pack"); + progress.set_name("Validating multi-pack".into()); progress.show_throughput(operation_start); Ok(integrity::Outcome { diff --git a/gix-pack/src/multi_index/write.rs b/gix-pack/src/multi_index/write.rs index 9002af9eb74..94ad327c382 100644 --- a/gix-pack/src/multi_index/write.rs +++ b/gix-pack/src/multi_index/write.rs @@ -5,7 +5,7 @@ use std::{ time::{Instant, SystemTime}, }; -use gix_features::progress::Progress; +use gix_features::progress::{Count, NestedProgress, Progress}; use crate::multi_index; @@ -87,7 +87,7 @@ impl multi_index::File { Options { object_hash }: Options, ) -> Result, Error> where - P: Progress, + P: NestedProgress, { let out = gix_features::hash::Write::new(out, object_hash); let (index_paths_sorted, index_filenames_sorted) = { @@ -129,7 +129,7 @@ impl multi_index::File { progress.show_throughput(start); let start = Instant::now(); - progress.set_name("Deduplicate"); + progress.set_name("Deduplicate".into()); progress.init(Some(entries.len()), gix_features::progress::count("entries")); entries.sort_by(|l, r| { l.id.cmp(&r.id) @@ -187,7 +187,7 @@ impl multi_index::File { )?; { - progress.set_name("Writing chunks"); + progress.set_name("Writing chunks".into()); progress.init(Some(cf.num_chunks()), gix_features::progress::count("chunks")); let mut chunk_write = cf.into_write(&mut out, bytes_written)?; diff --git a/gix-protocol/src/fetch/delegate.rs b/gix-protocol/src/fetch/delegate.rs index e90022d419e..5f8b86dceef 100644 --- a/gix-protocol/src/fetch/delegate.rs +++ b/gix-protocol/src/fetch/delegate.rs @@ -183,7 +183,7 @@ mod blocking_io { ops::DerefMut, }; - use gix_features::progress::Progress; + use gix_features::progress::NestedProgress; use crate::{ fetch::{DelegateBlocking, Response}, @@ -207,7 +207,7 @@ mod blocking_io { fn receive_pack( &mut self, input: impl io::BufRead, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()>; @@ -217,7 +217,7 @@ mod blocking_io { fn receive_pack( &mut self, input: impl BufRead, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()> { @@ -229,7 +229,7 @@ mod blocking_io { fn receive_pack( &mut self, input: impl BufRead, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()> { @@ -246,7 +246,7 @@ mod async_io { use async_trait::async_trait; use futures_io::AsyncBufRead; - use gix_features::progress::Progress; + use gix_features::progress::NestedProgress; use crate::{ fetch::{DelegateBlocking, Response}, @@ -272,7 +272,7 @@ mod async_io { async fn receive_pack( &mut self, input: impl AsyncBufRead + Unpin + 'async_trait, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()>; @@ -282,7 +282,7 @@ mod async_io { async fn receive_pack( &mut self, input: impl AsyncBufRead + Unpin + 'async_trait, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()> { @@ -297,7 +297,7 @@ mod async_io { async fn receive_pack( &mut self, input: impl AsyncBufRead + Unpin + 'async_trait, - progress: impl Progress, + progress: impl NestedProgress, refs: &[Ref], previous_response: &Response, ) -> io::Result<()> { diff --git a/gix-protocol/src/fetch_fn.rs b/gix-protocol/src/fetch_fn.rs index 64d457711b2..be5e9471248 100644 --- a/gix-protocol/src/fetch_fn.rs +++ b/gix-protocol/src/fetch_fn.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use gix_features::progress::Progress; +use gix_features::progress::NestedProgress; use gix_transport::client; use maybe_async::maybe_async; @@ -59,7 +59,7 @@ where F: FnMut(credentials::helper::Action) -> credentials::protocol::Result, D: Delegate, T: client::Transport, - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { let crate::handshake::Outcome { @@ -136,7 +136,7 @@ where .await?; previous_response = if response.has_pack() { progress.step(); - progress.set_name("receiving pack"); + progress.set_name("receiving pack".into()); if !sideband_all { setup_remote_progress(&mut progress, &mut reader); } @@ -159,7 +159,7 @@ where fn setup_remote_progress

(progress: &mut P, reader: &mut Box) where - P: Progress, + P: NestedProgress, P::SubProgress: 'static, { reader.set_progress_handler(Some(Box::new({ diff --git a/gix-protocol/src/handshake/function.rs b/gix-protocol/src/handshake/function.rs index 5398a1bedb5..9e75c18d0dc 100644 --- a/gix-protocol/src/handshake/function.rs +++ b/gix-protocol/src/handshake/function.rs @@ -24,7 +24,7 @@ where { let (server_protocol_version, refs, capabilities) = { progress.init(None, progress::steps()); - progress.set_name("handshake"); + progress.set_name("handshake".into()); progress.step(); let extra_parameters: Vec<_> = extra_parameters @@ -43,13 +43,13 @@ where Err(client::Error::Io(ref err)) if err.kind() == std::io::ErrorKind::PermissionDenied => { drop(result); // needed to workaround this: https://github.com/rust-lang/rust/issues/76149 let url = transport.to_url().into_owned(); - progress.set_name("authentication"); + progress.set_name("authentication".into()); let credentials::protocol::Outcome { identity, next } = authenticate(credentials::helper::Action::get_for_url(url.clone()))? .ok_or(Error::EmptyCredentials)?; transport.set_identity(identity)?; progress.step(); - progress.set_name("handshake (authenticated)"); + progress.set_name("handshake (authenticated)".into()); match transport.handshake(service, &extra_parameters).await { Ok(v) => { authenticate(next.store())?; diff --git a/gix-protocol/src/ls_refs.rs b/gix-protocol/src/ls_refs.rs index d0b2e9ba083..c5b71da9337 100644 --- a/gix-protocol/src/ls_refs.rs +++ b/gix-protocol/src/ls_refs.rs @@ -86,7 +86,7 @@ pub(crate) mod function { ); progress.step(); - progress.set_name("list refs"); + progress.set_name("list refs".into()); let mut remote_refs = transport .invoke( ls_refs.as_str(), diff --git a/gix-worktree-state/src/checkout/chunk.rs b/gix-worktree-state/src/checkout/chunk.rs index 930e70b89be..5e5a3c0fb28 100644 --- a/gix-worktree-state/src/checkout/chunk.rs +++ b/gix-worktree-state/src/checkout/chunk.rs @@ -12,21 +12,15 @@ use crate::{checkout, checkout::entry}; mod reduce { use std::marker::PhantomData; - use gix_features::progress::Progress; - use crate::checkout; - pub struct Reduce<'a, 'entry, P1, P2, E> { - pub files: Option<&'a mut P1>, - pub bytes: Option<&'a mut P2>, + pub struct Reduce<'entry, E> { pub aggregate: super::Outcome<'entry>, pub marker: PhantomData, } - impl<'a, 'entry, P1, P2, E> gix_features::parallel::Reduce for Reduce<'a, 'entry, P1, P2, E> + impl<'entry, E> gix_features::parallel::Reduce for Reduce<'entry, E> where - P1: Progress, - P2: Progress, E: std::error::Error + Send + Sync + 'static, { type Input = Result, checkout::Error>; @@ -55,13 +49,6 @@ mod reduce { .delayed_paths_unprocessed .extend(delayed_paths_unprocessed); - if let Some(progress) = self.bytes.as_deref_mut() { - progress.set(self.aggregate.bytes_written as gix_features::progress::Step); - } - if let Some(progress) = self.files.as_deref_mut() { - progress.set(self.aggregate.files); - } - Ok(()) } @@ -121,8 +108,8 @@ impl From<&checkout::Options> for Options { pub fn process<'entry, Find, E>( entries_with_paths: impl Iterator, - files: Option<&AtomicUsize>, - bytes: Option<&AtomicUsize>, + files: &AtomicUsize, + bytes: &AtomicUsize, delayed_filter_results: &mut Vec>, ctx: &mut Context, ) -> Result, checkout::Error> @@ -139,9 +126,7 @@ where for (entry, entry_path) in entries_with_paths { // TODO: write test for that if entry.flags.contains(gix_index::entry::Flags::SKIP_WORKTREE) { - if let Some(files) = files { - files.fetch_add(1, Ordering::SeqCst); - } + files.fetch_add(1, Ordering::Relaxed); files_in_chunk += 1; continue; } @@ -179,8 +164,8 @@ where pub fn process_delayed_filter_results( mut delayed_filter_results: Vec>, - files: Option<&AtomicUsize>, - bytes: Option<&AtomicUsize>, + files: &AtomicUsize, + bytes: &AtomicUsize, out: &mut Outcome<'_>, ctx: &mut Context, ) -> Result<(), checkout::Error> @@ -259,9 +244,7 @@ where }), )?; delayed_files += 1; - if let Some(files) = files { - files.fetch_add(1, Ordering::SeqCst); - } + files.fetch_add(1, Ordering::Relaxed); } } } @@ -286,7 +269,7 @@ where pub struct WriteWithProgress<'a, T> { pub inner: T, - pub progress: Option<&'a AtomicUsize>, + pub progress: &'a AtomicUsize, } impl<'a, T> std::io::Write for WriteWithProgress<'a, T> @@ -295,9 +278,8 @@ where { fn write(&mut self, buf: &[u8]) -> std::io::Result { let written = self.inner.write(buf)?; - if let Some(progress) = self.progress { - progress.fetch_add(written as gix_features::progress::Step, Ordering::SeqCst); - } + self.progress + .fetch_add(written as gix_features::progress::Step, Ordering::SeqCst); Ok(written) } @@ -311,8 +293,8 @@ pub fn checkout_entry_handle_result<'entry, Find, E>( entry_path: &'entry BStr, errors: &mut Vec, collisions: &mut Vec, - files: Option<&AtomicUsize>, - bytes: Option<&AtomicUsize>, + files: &AtomicUsize, + bytes: &AtomicUsize, Context { find, path_cache, @@ -339,12 +321,8 @@ where match res { Ok(out) => { if let Some(num) = out.as_bytes() { - if let Some(bytes) = bytes { - bytes.fetch_add(num, Ordering::SeqCst); - } - if let Some(files) = files { - files.fetch_add(1, Ordering::SeqCst); - } + bytes.fetch_add(num, Ordering::Relaxed); + files.fetch_add(1, Ordering::Relaxed); } Ok(out) } @@ -359,7 +337,7 @@ where fn handle_error( err: E, entry_path: &BStr, - files: Option<&AtomicUsize>, + files: &AtomicUsize, errors: &mut Vec, keep_going: bool, ) -> Result<(), E> @@ -371,9 +349,7 @@ where path: entry_path.into(), error: Box::new(err), }); - if let Some(files) = files { - files.fetch_add(1, Ordering::SeqCst); - } + files.fetch_add(1, Ordering::Relaxed); Ok(()) } else { Err(err) @@ -384,7 +360,7 @@ fn is_collision( err: &std::io::Error, entry_path: &BStr, collisions: &mut Vec, - files: Option<&AtomicUsize>, + files: &AtomicUsize, ) -> bool { if !gix_fs::symlink::is_collision_error(err) { return false; @@ -396,8 +372,6 @@ fn is_collision( path: entry_path.into(), error_kind: err.kind(), }); - if let Some(files) = files { - files.fetch_add(1, Ordering::SeqCst); - } + files.fetch_add(1, Ordering::Relaxed); true } diff --git a/gix-worktree-state/src/checkout/function.rs b/gix-worktree-state/src/checkout/function.rs index 507d59bc5cc..58bafd511ee 100644 --- a/gix-worktree-state/src/checkout/function.rs +++ b/gix-worktree-state/src/checkout/function.rs @@ -89,18 +89,12 @@ where let mut delayed_filter_results = Vec::new(); let mut out = chunk::process( entries_with_paths, - num_files.as_deref(), - num_bytes.as_deref(), + &num_files, + &num_bytes, &mut delayed_filter_results, &mut ctx, )?; - chunk::process_delayed_filter_results( - delayed_filter_results, - num_files.as_deref(), - num_bytes.as_deref(), - &mut out, - &mut ctx, - )?; + chunk::process_delayed_filter_results(delayed_filter_results, &num_files, &num_bytes, &mut out, &mut ctx)?; out } else { let entries_with_paths = interrupt::Iter::new(index.entries_mut_with_paths_in(paths), should_interrupt); @@ -115,28 +109,20 @@ where move |_| (Vec::new(), ctx) }, |chunk, (delayed_filter_results, ctx)| { - chunk::process( - chunk.into_iter(), - num_files.as_deref(), - num_bytes.as_deref(), - delayed_filter_results, - ctx, - ) + chunk::process(chunk.into_iter(), &num_files, &num_bytes, delayed_filter_results, ctx) }, |(delayed_filter_results, mut ctx)| { let mut out = chunk::Outcome::default(); chunk::process_delayed_filter_results( delayed_filter_results, - num_files.as_deref(), - num_bytes.as_deref(), + &num_files, + &num_bytes, &mut out, &mut ctx, )?; Ok(out) }, chunk::Reduce { - files: num_files.is_none().then_some(files), - bytes: num_bytes.is_none().then_some(bytes), aggregate: Default::default(), marker: Default::default(), }, @@ -149,8 +135,8 @@ where entry_path, &mut errors, &mut collisions, - num_files.as_deref(), - num_bytes.as_deref(), + &num_files, + &num_bytes, &mut ctx, )? .as_bytes() diff --git a/gix/Cargo.toml b/gix/Cargo.toml index e63f2504e83..1244c1339fb 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -176,7 +176,7 @@ gix-protocol = { version = "^0.38.0", path = "../gix-protocol", optional = true gix-transport = { version = "^0.35.0", path = "../gix-transport", optional = true } # Just to get the progress-tree feature -prodash = { version = "25.0", optional = true, default-features = false, features = ["progress-tree"] } +prodash = { version = "26.0", optional = true, default-features = false, features = ["progress-tree"] } once_cell = "1.14.0" signal-hook = { version = "0.3.9", default-features = false } thiserror = "1.0.26" diff --git a/gix/src/clone/checkout.rs b/gix/src/clone/checkout.rs index a51b7197146..f896ee3ebd4 100644 --- a/gix/src/clone/checkout.rs +++ b/gix/src/clone/checkout.rs @@ -67,7 +67,7 @@ pub mod main_worktree { /// if the `head()` of the returned repository is not unborn. pub fn main_worktree( &mut self, - mut progress: impl crate::Progress, + mut progress: impl gix_features::progress::NestedProgress, should_interrupt: &AtomicBool, ) -> Result<(Repository, gix_worktree_state::checkout::Outcome), Error> { let _span = gix_trace::coarse!("gix::clone::PrepareCheckout::main_worktree()"); diff --git a/gix/src/clone/fetch/mod.rs b/gix/src/clone/fetch/mod.rs index 227281eb463..408fcca29cb 100644 --- a/gix/src/clone/fetch/mod.rs +++ b/gix/src/clone/fetch/mod.rs @@ -55,7 +55,7 @@ impl PrepareFetch { should_interrupt: &std::sync::atomic::AtomicBool, ) -> Result<(crate::Repository, crate::remote::fetch::Outcome), Error> where - P: crate::Progress, + P: crate::NestedProgress, P::SubProgress: 'static, { use crate::{bstr::ByteVec, remote, remote::fetch::RefLogMessage}; @@ -156,7 +156,7 @@ impl PrepareFetch { should_interrupt: &std::sync::atomic::AtomicBool, ) -> Result<(crate::clone::PrepareCheckout, crate::remote::fetch::Outcome), Error> where - P: crate::Progress, + P: crate::NestedProgress, P::SubProgress: 'static, { let (repo, fetch_outcome) = self.fetch_only(progress, should_interrupt)?; diff --git a/gix/src/lib.rs b/gix/src/lib.rs index 0db78f5b635..6fcc561894d 100644 --- a/gix/src/lib.rs +++ b/gix/src/lib.rs @@ -83,7 +83,11 @@ pub use gix_credentials as credentials; pub use gix_date as date; pub use gix_features as features; use gix_features::threading::OwnShared; -pub use gix_features::{parallel, progress::Progress, threading}; +pub use gix_features::{ + parallel, + progress::{Count, NestedProgress, Progress}, + threading, +}; pub use gix_fs as fs; pub use gix_glob as glob; pub use gix_hash as hash; diff --git a/gix/src/remote/connection/fetch/receive_pack.rs b/gix/src/remote/connection/fetch/receive_pack.rs index 089fe295721..a0cf2e3b7bc 100644 --- a/gix/src/remote/connection/fetch/receive_pack.rs +++ b/gix/src/remote/connection/fetch/receive_pack.rs @@ -23,7 +23,7 @@ use crate::{ Shallow, Status, }, }, - Progress, Repository, + Repository, }; impl<'remote, 'repo, T> Prepare<'remote, 'repo, T> @@ -75,7 +75,7 @@ where #[gix_protocol::maybe_async::maybe_async] pub async fn receive

(mut self, mut progress: P, should_interrupt: &AtomicBool) -> Result where - P: Progress, + P: gix_features::progress::NestedProgress, P::SubProgress: 'static, { let _span = gix_trace::coarse!("fetch::Prepare::receive()"); @@ -211,7 +211,7 @@ where previous_response = Some(response); if has_pack { progress.step(); - progress.set_name("receiving pack"); + progress.set_name("receiving pack".into()); if !sideband_all { setup_remote_progress(progress, &mut reader, should_interrupt); } @@ -377,7 +377,7 @@ fn setup_remote_progress

( reader: &mut Box, should_interrupt: &AtomicBool, ) where - P: Progress, + P: gix_features::progress::NestedProgress, P::SubProgress: 'static, { use gix_protocol::transport::client::ExtendedBufRead; diff --git a/gix/src/repository/worktree.rs b/gix/src/repository/worktree.rs index 8526e9de503..de5dac4b48d 100644 --- a/gix/src/repository/worktree.rs +++ b/gix/src/repository/worktree.rs @@ -114,7 +114,7 @@ impl crate::Repository { &self, mut stream: gix_worktree_stream::Stream, out: impl std::io::Write + std::io::Seek, - mut blobs: impl gix_features::progress::Progress, + blobs: impl gix_features::progress::Progress, should_interrupt: &std::sync::atomic::AtomicBool, options: gix_archive::Options, ) -> Result<(), crate::repository::worktree_archive::Error> { diff --git a/src/shared.rs b/src/shared.rs index 550c6c6c5ab..6abc14f78cc 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -112,11 +112,11 @@ pub mod pretty { let tree = tracing_forest::printer::Pretty.fmt(tree)?; if reverse_lines { for line in tree.lines().rev() { - progress.info(line); + progress.info(line.into()); } } else { for line in tree.lines() { - progress.info(line); + progress.info(line.into()); } } Ok(String::new()) From 24dd870919ba444aa8099c63a78ea120d47ec28e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 4 Sep 2023 19:25:57 +0200 Subject: [PATCH 3/4] feat!: use `prodash::Count` to indicate that nothing more than counting is performed, in place of `prodash::Progress` --- Cargo.lock | 10 +-- Cargo.toml | 2 +- gix-features/Cargo.toml | 2 +- gix-features/src/progress.rs | 4 +- gix-pack/src/data/file/verify.rs | 3 +- gix-pack/src/data/output/count/objects/mod.rs | 72 ++++++++----------- .../src/data/output/count/objects/reduce.rs | 21 ++---- .../pack/data/output/count_and_entries.rs | 2 +- gix-protocol/tests/fetch/mod.rs | 16 ++--- gix-worktree-state/src/checkout/function.rs | 10 +-- gix/Cargo.toml | 2 +- gix/src/repository/worktree.rs | 2 +- 12 files changed, 63 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc26aa3b7ea..bcf595ff7d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1137,7 +1137,7 @@ dependencies = [ "is-terminal", "once_cell", "owo-colors", - "prodash 26.0.0", + "prodash 26.2.0", "serde_derive", "tabled", "time", @@ -1237,7 +1237,7 @@ dependencies = [ "log", "once_cell", "parking_lot", - "prodash 26.0.0", + "prodash 26.2.0", "regex", "reqwest", "serde", @@ -1570,7 +1570,7 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash 26.0.0", + "prodash 26.2.0", "sha1", "sha1_smol", "thiserror", @@ -3503,9 +3503,9 @@ checksum = "9516b775656bc3e8985e19cd4b8c0c0de045095074e453d2c0a513b5f978392d" [[package]] name = "prodash" -version = "26.0.0" +version = "26.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c85fe210cada0bbfc863bddeac230f5894e00d1617aa32d924302a36cf3e965" +checksum = "0fdc60e4df7c418baa9fbfc62b5054b06745dfc3a2aee40294ad390b701f6351" dependencies = [ "async-io", "bytesize", diff --git a/Cargo.toml b/Cargo.toml index 0abeb689d3c..3bfc1bda5ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,7 +168,7 @@ gix = { version = "^0.53.0", path = "gix", default-features = false } time = "0.3.23" clap = { version = "4.1.1", features = ["derive", "cargo"] } -prodash = { version = "26.0.0", optional = true, default-features = false } +prodash = { version = "26.2.0", optional = true, default-features = false } is-terminal = { version = "0.4.0", optional = true } env_logger = { version = "0.10.0", default-features = false } crosstermion = { version = "0.11.0", optional = true, default-features = false } diff --git a/gix-features/Cargo.toml b/gix-features/Cargo.toml index 337eaec3ece..7af19f3a4b7 100644 --- a/gix-features/Cargo.toml +++ b/gix-features/Cargo.toml @@ -129,7 +129,7 @@ crc32fast = { version = "1.2.1", optional = true } sha1 = { version = "0.10.0", optional = true } # progress -prodash = { version = "26.0.0", optional = true, default-features = false } +prodash = { version = "26.2.0", optional = true, default-features = false } bytesize = { version = "1.0.1", optional = true } # pipe diff --git a/gix-features/src/progress.rs b/gix-features/src/progress.rs index 1f13fdab89d..eb3c27959a9 100644 --- a/gix-features/src/progress.rs +++ b/gix-features/src/progress.rs @@ -6,7 +6,9 @@ pub use bytesize; pub use prodash::{ self, messages::MessageLevel, - progress::{Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN}, + progress::{ + AtomicStep, Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN, + }, unit, Count, NestedProgress, Progress, Unit, }; /// A stub for the portions of the `bytesize` crate that we use internally in `gitoxide`. diff --git a/gix-pack/src/data/file/verify.rs b/gix-pack/src/data/file/verify.rs index afec208261a..df4aedf9dbf 100644 --- a/gix-pack/src/data/file/verify.rs +++ b/gix-pack/src/data/file/verify.rs @@ -1,6 +1,5 @@ -use std::sync::atomic::AtomicBool; - use gix_features::progress::Progress; +use std::sync::atomic::AtomicBool; use crate::data::File; diff --git a/gix-pack/src/data/output/count/objects/mod.rs b/gix-pack/src/data/output/count/objects/mod.rs index 3f9a28bd162..02f4b1ea04e 100644 --- a/gix-pack/src/data/output/count/objects/mod.rs +++ b/gix-pack/src/data/output/count/objects/mod.rs @@ -1,10 +1,6 @@ -use std::{ - cell::RefCell, - sync::{atomic::AtomicBool, Arc}, -}; +use std::{cell::RefCell, sync::atomic::AtomicBool}; -use gix_features::progress::NestedProgress; -use gix_features::{parallel, progress::Progress}; +use gix_features::parallel; use gix_hash::ObjectId; use crate::{data::output, find}; @@ -30,8 +26,8 @@ pub type Result = std::result::Result<(Vec, Outcome), Err /// * `objects_ids` /// * A list of objects ids to add to the pack. Duplication checks are performed so no object is ever added to a pack twice. /// * Objects may be expanded based on the provided [`options`][Options] -/// * `progress` -/// * a way to obtain progress information +/// * `objects` +/// * count the amount of objects we encounter /// * `should_interrupt` /// * A flag that is set to true if the operation should stop /// * `options` @@ -39,7 +35,7 @@ pub type Result = std::result::Result<(Vec, Outcome), Err pub fn objects( db: Find, objects_ids: Iter, - progress: impl NestedProgress, + objects: &dyn gix_features::progress::Count, should_interrupt: &AtomicBool, Options { thread_limit, @@ -66,30 +62,23 @@ where size: chunk_size, }; let seen_objs = gix_hashtable::sync::ObjectIdMap::default(); - let progress = Arc::new(parking_lot::Mutex::new(progress)); + let objects = objects.counter(); parallel::in_parallel( chunks, thread_limit, { - let progress = Arc::clone(&progress); - move |n| { + move |_| { ( Vec::new(), // object data buffer Vec::new(), // object data buffer 2 to hold two objects at a time - { - let mut p = progress - .lock() - .add_child_with_id(format!("thread {n}"), gix_features::progress::UNKNOWN); - p.init(None, gix_features::progress::count("objects")); - p - }, + objects.clone(), ) } }, { let seen_objs = &seen_objs; - move |oids: Vec>, (buf1, buf2, progress)| { + move |oids: Vec>, (buf1, buf2, objects)| { expand::this( &db, input_object_expansion, @@ -97,13 +86,13 @@ where oids, buf1, buf2, - progress, + objects, should_interrupt, true, /*allow pack lookups*/ ) } }, - reduce::Statistics::new(progress), + reduce::Statistics::new(), ) } @@ -111,7 +100,7 @@ where pub fn objects_unthreaded( db: Find, object_ids: impl Iterator>, - mut progress: impl Progress, + objects: impl gix_features::progress::Count, should_interrupt: &AtomicBool, input_object_expansion: ObjectExpansion, ) -> Result, IterErr> @@ -130,7 +119,7 @@ where object_ids, &mut buf1, &mut buf2, - &mut progress, + &objects.counter(), should_interrupt, false, /*allow pack lookups*/ ) @@ -139,7 +128,6 @@ where mod expand { use std::sync::atomic::{AtomicBool, Ordering}; - use gix_features::progress::Progress; use gix_hash::{oid, ObjectId}; use gix_object::{CommitRefIter, TagRefIter}; @@ -161,7 +149,7 @@ mod expand { oids: impl IntoIterator>, buf1: &mut Vec, #[allow(clippy::ptr_arg)] buf2: &mut Vec, - progress: &mut impl Progress, + objects: &gix_features::progress::AtomicStep, should_interrupt: &AtomicBool, allow_pack_lookups: bool, ) -> super::Result, IterErr> @@ -197,7 +185,7 @@ mod expand { let mut id = id.to_owned(); loop { - push_obj_count_unique(&mut out, seen_objs, &id, location, progress, stats, false); + push_obj_count_unique(&mut out, seen_objs, &id, location, objects, stats, false); match obj.kind { Tree | Blob => break, Tag => { @@ -228,12 +216,12 @@ mod expand { } let (obj, location) = db.find(tree_id, buf1)?; push_obj_count_unique( - &mut out, seen_objs, &tree_id, location, progress, stats, true, + &mut out, seen_objs, &tree_id, location, objects, stats, true, ); gix_object::TreeRefIter::from_bytes(obj.data) }; - let objects = if parent_commit_ids.is_empty() { + let objects_ref = if parent_commit_ids.is_empty() { traverse_delegate.clear(); gix_traverse::tree::breadthfirst( current_tree_iter, @@ -242,7 +230,7 @@ mod expand { stats.decoded_objects += 1; match db.find(oid, buf).ok() { Some((obj, location)) => { - progress.inc(); + objects.fetch_add(1, Ordering::Relaxed); stats.expanded_objects += 1; out.push(output::Count::from_data(oid, location)); obj.try_into_tree_iter() @@ -260,7 +248,7 @@ mod expand { let (parent_commit_obj, location) = db.find(commit_id, buf2)?; push_obj_count_unique( - &mut out, seen_objs, commit_id, location, progress, stats, true, + &mut out, seen_objs, commit_id, location, objects, stats, true, ); CommitRefIter::from_bytes(parent_commit_obj.data) .tree_id() @@ -273,7 +261,7 @@ mod expand { seen_objs, &parent_tree_id, location, - progress, + objects, stats, true, ); @@ -295,8 +283,8 @@ mod expand { } &changes_delegate.objects }; - for id in objects.iter() { - out.push(id_to_count(db, buf2, id, progress, stats, allow_pack_lookups)); + for id in objects_ref.iter() { + out.push(id_to_count(db, buf2, id, objects, stats, allow_pack_lookups)); } break; } @@ -308,7 +296,7 @@ mod expand { let mut id = id; let mut obj = (obj, location); loop { - push_obj_count_unique(&mut out, seen_objs, &id, obj.1.clone(), progress, stats, false); + push_obj_count_unique(&mut out, seen_objs, &id, obj.1.clone(), objects, stats, false); match obj.0.kind { Tree => { traverse_delegate.clear(); @@ -319,7 +307,7 @@ mod expand { stats.decoded_objects += 1; match db.find(oid, buf).ok() { Some((obj, location)) => { - progress.inc(); + objects.fetch_add(1, Ordering::Relaxed); stats.expanded_objects += 1; out.push(output::Count::from_data(oid, location)); obj.try_into_tree_iter() @@ -331,7 +319,7 @@ mod expand { ) .map_err(Error::TreeTraverse)?; for id in &traverse_delegate.non_trees { - out.push(id_to_count(db, buf1, id, progress, stats, allow_pack_lookups)); + out.push(id_to_count(db, buf1, id, objects, stats, allow_pack_lookups)); } break; } @@ -355,7 +343,7 @@ mod expand { } } } - AsIs => push_obj_count_unique(&mut out, seen_objs, &id, location, progress, stats, false), + AsIs => push_obj_count_unique(&mut out, seen_objs, &id, location, objects, stats, false), } } outcome.total_objects = out.len(); @@ -368,13 +356,13 @@ mod expand { all_seen: &impl util::InsertImmutable, id: &oid, location: Option, - progress: &mut impl Progress, + objects: &gix_features::progress::AtomicStep, statistics: &mut Outcome, count_expanded: bool, ) { let inserted = all_seen.insert(id.to_owned()); if inserted { - progress.inc(); + objects.fetch_add(1, Ordering::Relaxed); statistics.decoded_objects += 1; if count_expanded { statistics.expanded_objects += 1; @@ -388,11 +376,11 @@ mod expand { db: &Find, buf: &mut Vec, id: &oid, - progress: &mut impl Progress, + objects: &gix_features::progress::AtomicStep, statistics: &mut Outcome, allow_pack_lookups: bool, ) -> output::Count { - progress.inc(); + objects.fetch_add(1, Ordering::Relaxed); statistics.expanded_objects += 1; output::Count { id: id.to_owned(), diff --git a/gix-pack/src/data/output/count/objects/reduce.rs b/gix-pack/src/data/output/count/objects/reduce.rs index ebd686570b9..03144b60fd5 100644 --- a/gix-pack/src/data/output/count/objects/reduce.rs +++ b/gix-pack/src/data/output/count/objects/reduce.rs @@ -1,35 +1,27 @@ -use std::{marker::PhantomData, sync::Arc}; +use std::marker::PhantomData; -use gix_features::{parallel, progress::Progress}; +use gix_features::parallel; use super::Outcome; use crate::data::output; -pub struct Statistics { +pub struct Statistics { total: Outcome, counts: Vec, - progress: Arc>, _err: PhantomData, } -impl Statistics -where - P: Progress, -{ - pub fn new(progress: Arc>) -> Self { +impl Statistics { + pub fn new() -> Self { Statistics { total: Default::default(), counts: Default::default(), - progress, _err: PhantomData, } } } -impl parallel::Reduce for Statistics -where - P: Progress, -{ +impl parallel::Reduce for Statistics { type Input = Result<(Vec, Outcome), E>; type FeedProduce = (); type Output = (Vec, Outcome); @@ -38,7 +30,6 @@ where fn feed(&mut self, item: Self::Input) -> Result { let (counts, stats) = item?; self.total.aggregate(stats); - self.progress.lock().inc_by(counts.len()); self.counts.extend(counts); Ok(()) } diff --git a/gix-pack/tests/pack/data/output/count_and_entries.rs b/gix-pack/tests/pack/data/output/count_and_entries.rs index d5bd9bbd474..1cece6a0f1a 100644 --- a/gix-pack/tests/pack/data/output/count_and_entries.rs +++ b/gix-pack/tests/pack/data/output/count_and_entries.rs @@ -264,7 +264,7 @@ fn traversals() -> crate::Result { }))) .filter(|o| !o.is_null()) .map(Ok::<_, Infallible>), - progress::Discard, + &progress::Discard, &AtomicBool::new(false), count::objects::Options { input_object_expansion: expansion_mode, diff --git a/gix-protocol/tests/fetch/mod.rs b/gix-protocol/tests/fetch/mod.rs index 1639ebd0840..4516234ebc4 100644 --- a/gix-protocol/tests/fetch/mod.rs +++ b/gix-protocol/tests/fetch/mod.rs @@ -150,9 +150,9 @@ impl fetch::DelegateBlocking for LsRemoteDelegate { #[cfg(feature = "blocking-client")] mod blocking_io { + use gix_features::progress::NestedProgress; use std::io; - use gix_features::progress::Progress; use gix_protocol::{fetch, fetch::Response, handshake, handshake::Ref}; use crate::fetch::{CloneDelegate, CloneRefInWantDelegate, LsRemoteDelegate}; @@ -161,7 +161,7 @@ mod blocking_io { fn receive_pack( &mut self, mut input: impl io::BufRead, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -174,7 +174,7 @@ mod blocking_io { fn receive_pack( &mut self, mut input: impl io::BufRead, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], response: &Response, ) -> io::Result<()> { @@ -193,7 +193,7 @@ mod blocking_io { fn receive_pack( &mut self, _input: impl io::BufRead, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -208,7 +208,7 @@ mod async_io { use async_trait::async_trait; use futures_io::AsyncBufRead; - use gix_features::progress::Progress; + use gix_features::progress::NestedProgress; use gix_protocol::{fetch, fetch::Response, handshake, handshake::Ref}; use crate::fetch::{CloneDelegate, CloneRefInWantDelegate, LsRemoteDelegate}; @@ -218,7 +218,7 @@ mod async_io { async fn receive_pack( &mut self, mut input: impl AsyncBufRead + Unpin + 'async_trait, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -232,7 +232,7 @@ mod async_io { async fn receive_pack( &mut self, mut input: impl AsyncBufRead + Unpin + 'async_trait, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], response: &Response, ) -> io::Result<()> { @@ -252,7 +252,7 @@ mod async_io { async fn receive_pack( &mut self, _input: impl AsyncBufRead + Unpin + 'async_trait, - _progress: impl Progress, + _progress: impl NestedProgress, _refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { diff --git a/gix-worktree-state/src/checkout/function.rs b/gix-worktree-state/src/checkout/function.rs index 58bafd511ee..4e3f454ccdd 100644 --- a/gix-worktree-state/src/checkout/function.rs +++ b/gix-worktree-state/src/checkout/function.rs @@ -1,6 +1,6 @@ use std::sync::atomic::AtomicBool; -use gix_features::{interrupt, parallel::in_parallel_with_finalize, progress::Progress}; +use gix_features::{interrupt, parallel::in_parallel_with_finalize}; use gix_hash::oid; use gix_worktree::{stack, Stack}; @@ -21,8 +21,8 @@ pub fn checkout( index: &mut gix_index::State, dir: impl Into, find: Find, - files: &mut impl Progress, - bytes: &mut impl Progress, + files: &dyn gix_features::progress::Count, + bytes: &dyn gix_features::progress::Count, should_interrupt: &AtomicBool, options: crate::checkout::Options, ) -> Result> @@ -42,8 +42,8 @@ fn checkout_inner( paths: &gix_index::PathStorage, dir: impl Into, find: Find, - files: &mut impl Progress, - bytes: &mut impl Progress, + files: &dyn gix_features::progress::Count, + bytes: &dyn gix_features::progress::Count, should_interrupt: &AtomicBool, mut options: crate::checkout::Options, ) -> Result> diff --git a/gix/Cargo.toml b/gix/Cargo.toml index 1244c1339fb..ae052aa527b 100644 --- a/gix/Cargo.toml +++ b/gix/Cargo.toml @@ -176,7 +176,7 @@ gix-protocol = { version = "^0.38.0", path = "../gix-protocol", optional = true gix-transport = { version = "^0.35.0", path = "../gix-transport", optional = true } # Just to get the progress-tree feature -prodash = { version = "26.0", optional = true, default-features = false, features = ["progress-tree"] } +prodash = { version = "26.2", optional = true, default-features = false, features = ["progress-tree"] } once_cell = "1.14.0" signal-hook = { version = "0.3.9", default-features = false } thiserror = "1.0.26" diff --git a/gix/src/repository/worktree.rs b/gix/src/repository/worktree.rs index de5dac4b48d..cf0e98d6094 100644 --- a/gix/src/repository/worktree.rs +++ b/gix/src/repository/worktree.rs @@ -114,7 +114,7 @@ impl crate::Repository { &self, mut stream: gix_worktree_stream::Stream, out: impl std::io::Write + std::io::Seek, - blobs: impl gix_features::progress::Progress, + blobs: impl gix_features::progress::Count, should_interrupt: &std::sync::atomic::AtomicBool, options: gix_archive::Options, ) -> Result<(), crate::repository::worktree_archive::Error> { From 072ee32f693a31161cd6a843da6582d13efbb20b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 6 Sep 2023 13:46:41 +0200 Subject: [PATCH 4/4] fix!: use `dyn` trait where possible. This reduces compile time due to avoiding duplication. --- Cargo.lock | 10 +- gitoxide-core/src/commitgraph/verify.rs | 2 +- gitoxide-core/src/corpus/run.rs | 3 +- gitoxide-core/src/index/checkout.rs | 8 +- gitoxide-core/src/organize.rs | 4 +- gitoxide-core/src/pack/create.rs | 21 ++-- gitoxide-core/src/pack/explode.rs | 31 +++--- gitoxide-core/src/pack/index.rs | 16 +-- gitoxide-core/src/pack/multi_index.rs | 8 +- gitoxide-core/src/pack/receive.rs | 22 ++-- gitoxide-core/src/pack/verify.rs | 8 +- gitoxide-core/src/repository/archive.rs | 2 +- .../src/repository/attributes/query.rs | 6 +- gitoxide-core/src/repository/clone.rs | 3 +- gitoxide-core/src/repository/exclude.rs | 8 +- gitoxide-core/src/repository/index/entries.rs | 42 +++---- gitoxide-core/src/repository/verify.rs | 8 +- gix-actor/src/identity.rs | 4 +- gix-actor/src/signature/mod.rs | 4 +- gix-actor/tests/signature/mod.rs | 6 +- gix-attributes/src/search/attributes.rs | 15 ++- gix-attributes/src/search/outcome.rs | 11 +- gix-attributes/tests/search/mod.rs | 10 +- gix-commitgraph/src/file/access.rs | 5 +- gix-commitgraph/src/file/verify.rs | 3 +- gix-commitgraph/src/init.rs | 17 ++- gix-commitgraph/src/lib.rs | 2 +- gix-commitgraph/tests/commitgraph.rs | 3 +- gix-config/fuzz/fuzz_targets/parse.rs | 2 +- gix-config/src/file/access/comfort.rs | 31 +++--- gix-config/src/file/access/mutate.rs | 56 ++++++++-- gix-config/src/file/access/raw.rs | 52 +++++++-- gix-config/src/file/access/read_only.rs | 13 +-- gix-config/src/file/init/comfort.rs | 6 +- gix-config/src/file/init/from_paths.rs | 17 +-- gix-config/src/file/mutable/section.rs | 10 +- gix-config/src/file/section/body.rs | 14 +-- gix-config/src/file/section/mod.rs | 2 +- gix-config/src/file/write.rs | 8 +- gix-config/src/parse/event.rs | 2 +- gix-config/src/parse/events.rs | 8 +- gix-config/src/parse/key.rs | 3 +- gix-config/src/parse/nom/mod.rs | 12 +- gix-config/tests/config.rs | 2 +- gix-config/tests/file/init/from_env.rs | 2 +- gix-config/tests/file/mod.rs | 2 +- gix-config/tests/file/mutable/section.rs | 6 +- gix-config/tests/file/write.rs | 2 +- gix-config/tests/parse/key.rs | 8 +- gix-credentials/src/helper/invoke.rs | 7 +- gix-credentials/src/program/mod.rs | 42 +++---- gix-date/src/time/format.rs | 6 +- gix-date/src/time/write.rs | 2 +- gix-date/tests/time/baseline.rs | 2 +- gix-diff/tests/diff.rs | 2 +- gix-diff/tests/tree/mod.rs | 10 +- gix-discover/src/is.rs | 22 ++-- gix-discover/src/path.rs | 8 +- gix-discover/src/repository.rs | 13 +-- gix-discover/src/upwards/mod.rs | 17 ++- gix-discover/src/upwards/util.rs | 4 +- gix-discover/tests/is_git/mod.rs | 12 +- gix-discover/tests/isolated.rs | 16 +-- gix-discover/tests/upwards/ceiling_dirs.rs | 20 ++-- gix-discover/tests/upwards/mod.rs | 28 ++--- gix-features/src/cache.rs | 6 +- gix-features/src/fs.rs | 8 +- gix-features/src/hash.rs | 10 +- gix-features/src/io.rs | 6 +- gix-features/src/progress.rs | 2 +- gix-features/tests/pipe.rs | 4 +- gix-filter/examples/arrow.rs | 2 +- gix-filter/src/driver/apply.rs | 2 +- gix-filter/src/driver/delayed.rs | 8 +- gix-filter/src/driver/process/client.rs | 16 +-- gix-filter/src/driver/process/server.rs | 2 +- gix-filter/src/eol/convert_to_git.rs | 19 ++-- gix-filter/src/pipeline/convert.rs | 20 ++-- gix-filter/src/pipeline/util.rs | 2 +- gix-filter/tests/driver/mod.rs | 12 +- gix-filter/tests/eol/convert_to_git.rs | 32 +++--- gix-filter/tests/filter.rs | 2 +- gix-filter/tests/pipeline/convert_to_git.rs | 23 ++-- .../tests/pipeline/convert_to_worktree.rs | 6 +- gix-filter/tests/pipeline/mod.rs | 7 +- gix-fs/src/capabilities.rs | 11 +- gix-fs/src/dir/create.rs | 14 +-- gix-fs/src/dir/remove.rs | 3 +- gix-fs/src/stack.rs | 10 +- gix-fs/tests/dir/remove.rs | 2 +- gix-fs/tests/stack/mod.rs | 20 ++-- gix-glob/src/pattern.rs | 8 +- gix-glob/src/search/mod.rs | 9 +- gix-glob/src/search/pattern.rs | 10 +- gix-glob/tests/pattern/matching.rs | 4 +- gix-glob/tests/search/pattern.rs | 6 +- gix-glob/tests/wildmatch/mod.rs | 2 +- gix-hash/src/oid.rs | 2 +- gix-hash/src/prefix.rs | 3 +- gix-hash/tests/prefix/mod.rs | 10 +- gix-ignore/src/search.rs | 19 ++-- gix-ignore/tests/search/mod.rs | 12 +- gix-index/src/file/init.rs | 4 +- gix-lock/src/acquire.rs | 6 +- gix-negotiate/src/lib.rs | 4 +- gix-negotiate/tests/baseline/mod.rs | 10 +- gix-negotiate/tests/negotiate.rs | 6 +- gix-object/src/blob.rs | 20 ++-- gix-object/src/commit/write.rs | 4 +- gix-object/src/data.rs | 3 +- gix-object/src/encode.rs | 18 +-- gix-object/src/object/mod.rs | 20 ++-- gix-object/src/tag/write.rs | 12 +- gix-object/src/traits.rs | 12 +- gix-object/src/tree/write.rs | 4 +- gix-object/tests/object.rs | 2 +- gix-odb/src/alternate/mod.rs | 15 +-- gix-odb/src/cache.rs | 30 ++--- gix-odb/src/find.rs | 14 ++- gix-odb/src/lib.rs | 13 ++- gix-odb/src/sink.rs | 14 +-- gix-odb/src/store_impls/dynamic/find.rs | 34 ++---- gix-odb/src/store_impls/dynamic/handle.rs | 4 +- gix-odb/src/store_impls/dynamic/header.rs | 10 +- gix-odb/src/store_impls/dynamic/init.rs | 9 +- gix-odb/src/store_impls/dynamic/load_index.rs | 2 +- gix-odb/src/store_impls/dynamic/prefix.rs | 4 +- gix-odb/src/store_impls/dynamic/verify.rs | 42 +++---- gix-odb/src/store_impls/dynamic/write.rs | 7 +- gix-odb/src/store_impls/loose/find.rs | 18 +-- gix-odb/src/store_impls/loose/verify.rs | 8 +- gix-odb/src/store_impls/loose/write.rs | 36 +++--- gix-odb/src/traits.rs | 104 ++++++------------ gix-odb/tests/odb/alternate/mod.rs | 6 +- gix-odb/tests/odb/find/mod.rs | 2 +- gix-odb/tests/odb/header/mod.rs | 2 +- gix-odb/tests/odb/mod.rs | 2 +- gix-odb/tests/odb/regression/mod.rs | 2 +- gix-odb/tests/odb/sink/mod.rs | 2 +- gix-odb/tests/odb/store/compound.rs | 2 +- gix-odb/tests/odb/store/dynamic.rs | 95 ++++++++-------- gix-odb/tests/odb/store/linked.rs | 12 +- gix-odb/tests/odb/store/loose.rs | 40 +++---- gix-pack/src/bundle/find.rs | 8 +- gix-pack/src/bundle/mod.rs | 14 +-- gix-pack/src/bundle/write/mod.rs | 51 ++++----- gix-pack/src/cache/delta/from_offsets.rs | 8 +- gix-pack/src/cache/delta/mod.rs | 8 +- gix-pack/src/cache/delta/traverse/mod.rs | 22 ++-- gix-pack/src/cache/delta/traverse/resolve.rs | 22 ++-- gix-pack/src/data/entry/decode.rs | 8 +- gix-pack/src/data/entry/header.rs | 4 +- gix-pack/src/data/file/decode/entry.rs | 8 +- gix-pack/src/data/file/decode/header.rs | 2 +- gix-pack/src/data/file/verify.rs | 2 +- gix-pack/src/data/input/bytes_to_entries.rs | 2 +- gix-pack/src/data/input/entry.rs | 2 +- .../data/input/lookup_ref_delta_objects.rs | 12 +- gix-pack/src/data/output/count/mod.rs | 2 +- gix-pack/src/data/output/count/objects/mod.rs | 71 +++++------- .../src/data/output/count/objects/types.rs | 10 +- .../src/data/output/entry/iter_from_counts.rs | 27 ++--- gix-pack/src/data/output/entry/mod.rs | 9 +- gix-pack/src/find.rs | 21 ++-- gix-pack/src/find_traits.rs | 82 ++++++-------- gix-pack/src/index/access.rs | 11 +- gix-pack/src/index/traverse/mod.rs | 19 ++-- gix-pack/src/index/traverse/with_index.rs | 37 ++++--- gix-pack/src/index/traverse/with_lookup.rs | 24 ++-- gix-pack/src/index/util.rs | 2 +- gix-pack/src/index/verify.rs | 20 ++-- gix-pack/src/index/write/encode.rs | 20 ++-- gix-pack/src/index/write/mod.rs | 28 +++-- gix-pack/src/multi_index/access.rs | 4 +- gix-pack/src/multi_index/chunk.rs | 12 +- gix-pack/src/multi_index/verify.rs | 46 ++++---- gix-pack/src/multi_index/write.rs | 33 +++--- gix-pack/src/verify.rs | 4 +- gix-pack/tests/pack/bundle.rs | 10 +- gix-pack/tests/pack/data/file.rs | 6 +- .../pack/data/output/count_and_entries.rs | 40 +++---- gix-pack/tests/pack/data/output/mod.rs | 2 +- gix-pack/tests/pack/index.rs | 12 +- gix-pack/tests/pack/mod.rs | 2 +- gix-pack/tests/pack/multi_index/access.rs | 6 +- gix-pack/tests/pack/multi_index/verify.rs | 4 +- gix-pack/tests/pack/multi_index/write.rs | 8 +- gix-path/src/convert.rs | 4 +- gix-path/src/realpath.rs | 7 +- gix-path/tests/convert/normalize.rs | 49 ++++++--- gix-path/tests/realpath/mod.rs | 23 ++-- gix-pathspec/src/defaults.rs | 2 +- gix-pathspec/src/pattern.rs | 4 +- gix-pathspec/src/search/init.rs | 64 ++++++----- gix-pathspec/src/search/matching.rs | 7 +- gix-pathspec/tests/defaults.rs | 12 +- gix-pathspec/tests/search/mod.rs | 16 ++- gix-protocol/src/fetch/delegate.rs | 12 +- gix-protocol/src/fetch_fn.rs | 2 +- gix-ref/src/fullname.rs | 2 +- gix-ref/src/name.rs | 8 +- gix-ref/src/namespace.rs | 5 +- gix-ref/src/peel.rs | 3 +- gix-ref/src/store/file/find.rs | 2 +- gix-ref/src/store/file/log/line.rs | 4 +- gix-ref/src/store/file/loose/iter.rs | 7 +- gix-ref/src/store/file/loose/mod.rs | 12 +- gix-ref/src/store/file/loose/reflog.rs | 2 +- .../loose/reflog/create_or_update/tests.rs | 2 +- gix-ref/src/store/file/overlay_iter.rs | 13 +-- gix-ref/src/store/file/raw_ext.rs | 32 +++--- gix-ref/src/store/file/transaction/prepare.rs | 24 +++- gix-ref/src/store/general/init.rs | 7 +- gix-ref/src/store/packed/buffer.rs | 3 +- gix-ref/src/store/packed/iter.rs | 3 +- gix-ref/src/store/packed/transaction.rs | 6 +- gix-ref/src/transaction/ext.rs | 12 +- gix-ref/tests/file/reference.rs | 14 +-- gix-ref/tests/file/store/find.rs | 8 +- gix-ref/tests/file/store/iter.rs | 14 +-- gix-ref/tests/file/transaction/mod.rs | 6 +- .../create_or_update/mod.rs | 6 +- gix-ref/tests/file/worktree.rs | 21 ++-- gix-ref/tests/namespace/mod.rs | 2 +- gix-ref/tests/packed/iter.rs | 10 +- gix-ref/tests/refs.rs | 2 +- gix-ref/tests/transaction/mod.rs | 24 ++-- gix-refspec/src/write.rs | 4 +- gix-revision/src/describe.rs | 4 +- gix-revision/tests/describe/mod.rs | 2 +- gix-revwalk/src/graph/mod.rs | 20 ++-- gix-sec/src/identity.rs | 9 +- gix-sec/src/trust.rs | 4 +- gix-sec/tests/identity/mod.rs | 4 +- gix-status/tests/status/index_as_worktree.rs | 2 +- gix-submodule/src/access.rs | 18 +-- gix-submodule/src/is_active_platform.rs | 2 +- gix-submodule/src/lib.rs | 2 +- gix-tempfile/src/forksafe.rs | 6 +- gix-tempfile/src/handle.rs | 18 +-- gix-tempfile/src/lib.rs | 2 +- .../client/blocking_io/http/curl/remote.rs | 2 +- gix-traverse/tests/traverse.rs | 2 +- gix-traverse/tests/tree/mod.rs | 12 +- gix-url/src/lib.rs | 7 +- gix-url/tests/access/mod.rs | 9 +- gix-worktree-state/src/checkout/entry.rs | 2 +- gix-worktree-state/tests/state/checkout.rs | 6 +- gix-worktree-stream/src/from_tree/traverse.rs | 2 +- gix-worktree/src/stack/delegate.rs | 18 +-- gix-worktree/src/stack/mod.rs | 7 +- gix-worktree/src/stack/state/attributes.rs | 13 +-- gix-worktree/src/stack/state/ignore.rs | 11 +- gix-worktree/tests/worktree/mod.rs | 2 +- gix-worktree/tests/worktree/stack/ignore.rs | 2 +- gix-worktree/tests/worktree/stack/mod.rs | 2 +- gix/src/clone/checkout.rs | 9 +- gix/src/clone/fetch/util.rs | 9 +- gix/src/commit.rs | 2 +- gix/src/config/cache/access.rs | 2 +- gix/src/config/cache/init.rs | 4 +- gix/src/config/overrides.rs | 8 +- gix/src/config/snapshot/access.rs | 5 +- gix/src/create.rs | 2 +- gix/src/discover.rs | 2 +- gix/src/filter.rs | 8 +- gix/src/object/errors.rs | 10 +- gix/src/object/tree/mod.rs | 4 +- gix/src/open/repository.rs | 12 +- gix/src/pathspec.rs | 9 +- gix/src/reference/iter.rs | 12 +- gix/src/reference/mod.rs | 4 +- gix/src/remote/connect.rs | 6 +- .../remote/connection/fetch/receive_pack.rs | 36 +++--- .../connection/fetch/update_refs/mod.rs | 3 +- .../connection/fetch/update_refs/tests.rs | 2 +- gix/src/repository/object.rs | 18 +-- gix/src/revision/walk.rs | 2 +- gix/src/submodule/mod.rs | 2 +- gix/tests/clone/mod.rs | 5 +- gix/tests/remote/fetch.rs | 1 + gix/tests/remote/save.rs | 7 +- gix/tests/repository/object.rs | 2 +- gix/tests/repository/shallow.rs | 3 +- gix/tests/repository/worktree.rs | 5 +- gix/tests/revision/spec/from_bytes/util.rs | 1 + gix/tests/util/mod.rs | 2 +- src/shared.rs | 2 +- tests/tools/src/lib.rs | 2 +- 289 files changed, 1694 insertions(+), 1641 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcf595ff7d9..6458d8165e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1137,7 +1137,7 @@ dependencies = [ "is-terminal", "once_cell", "owo-colors", - "prodash 26.2.0", + "prodash 26.2.1", "serde_derive", "tabled", "time", @@ -1237,7 +1237,7 @@ dependencies = [ "log", "once_cell", "parking_lot", - "prodash 26.2.0", + "prodash 26.2.1", "regex", "reqwest", "serde", @@ -1570,7 +1570,7 @@ dependencies = [ "libc", "once_cell", "parking_lot", - "prodash 26.2.0", + "prodash 26.2.1", "sha1", "sha1_smol", "thiserror", @@ -3503,9 +3503,9 @@ checksum = "9516b775656bc3e8985e19cd4b8c0c0de045095074e453d2c0a513b5f978392d" [[package]] name = "prodash" -version = "26.2.0" +version = "26.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdc60e4df7c418baa9fbfc62b5054b06745dfc3a2aee40294ad390b701f6351" +checksum = "50bcc40e3e88402f12b15f94d43a2c7673365e9601cc52795e119b95a266100c" dependencies = [ "async-io", "bytesize", diff --git a/gitoxide-core/src/commitgraph/verify.rs b/gitoxide-core/src/commitgraph/verify.rs index 3a4623a1c21..8d601a762d3 100644 --- a/gitoxide-core/src/commitgraph/verify.rs +++ b/gitoxide-core/src/commitgraph/verify.rs @@ -39,7 +39,7 @@ pub(crate) mod function { W1: io::Write, W2: io::Write, { - let g = Graph::at(path).with_context(|| "Could not open commit graph")?; + let g = Graph::at(path.as_ref()).with_context(|| "Could not open commit graph")?; #[allow(clippy::unnecessary_wraps, unknown_lints)] fn noop_processor(_commit: &gix::commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> { diff --git a/gitoxide-core/src/corpus/run.rs b/gitoxide-core/src/corpus/run.rs index fb924fc1d05..1cabea65115 100644 --- a/gitoxide-core/src/corpus/run.rs +++ b/gitoxide-core/src/corpus/run.rs @@ -1,3 +1,4 @@ +use gix::progress::DynNestedProgress; use std::{path::Path, sync::atomic::AtomicBool}; use crate::{ @@ -141,7 +142,7 @@ impl Execute for VerifyOdb { crate::repository::verify::integrity( repo, std::io::sink(), - progress, + progress.add_child("integrity".into()), should_interrupt, crate::repository::verify::Context { output_statistics: None, diff --git a/gitoxide-core/src/index/checkout.rs b/gitoxide-core/src/index/checkout.rs index 5ecb3688860..f7f31432c7d 100644 --- a/gitoxide-core/src/index/checkout.rs +++ b/gitoxide-core/src/index/checkout.rs @@ -104,8 +104,8 @@ pub fn checkout_exclusive( } } }, - &mut files, - &mut bytes, + &files, + &bytes, should_interrupt, opts, ), @@ -116,8 +116,8 @@ pub fn checkout_exclusive( buf.clear(); Ok(gix::objs::BlobRef { data: buf }) }, - &mut files, - &mut bytes, + &files, + &bytes, should_interrupt, opts, ), diff --git a/gitoxide-core/src/organize.rs b/gitoxide-core/src/organize.rs index 1feed705a18..04764c2df5d 100644 --- a/gitoxide-core/src/organize.rs +++ b/gitoxide-core/src/organize.rs @@ -92,8 +92,8 @@ pub fn find_git_repository_workdirs( fn find_origin_remote(repo: &Path) -> anyhow::Result> { let non_bare = repo.join(".git").join("config"); let local = gix::config::Source::Local; - let config = gix::config::File::from_path_no_includes(non_bare.as_path(), local) - .or_else(|_| gix::config::File::from_path_no_includes(repo.join("config").as_path(), local))?; + let config = gix::config::File::from_path_no_includes(non_bare.as_path().into(), local) + .or_else(|_| gix::config::File::from_path_no_includes(repo.join("config"), local))?; Ok(config .string_by_key("remote.origin.url") .map(|url| gix_url::Url::from_bytes(url.as_ref())) diff --git a/gitoxide-core/src/pack/create.rs b/gitoxide-core/src/pack/create.rs index 7501e22a27f..6b3d3d65d8c 100644 --- a/gitoxide-core/src/pack/create.rs +++ b/gitoxide-core/src/pack/create.rs @@ -112,14 +112,13 @@ where P: NestedProgress, P::SubProgress: 'static, { + type ObjectIdIter = dyn Iterator>> + Send; + let repo = gix::discover(repository_path)?.into_sync(); progress.init(Some(2), progress::steps()); let tips = tips.into_iter(); let make_cancellation_err = || anyhow!("Cancelled by user"); - let (mut handle, input): ( - _, - Box> + Send>, - ) = match input { + let (mut handle, mut input): (_, Box) = match input { None => { let mut progress = progress.add_child("traversing"); progress.init(None, progress::count("commits")); @@ -141,7 +140,7 @@ where let handle = handle.clone(); move |oid, buf| handle.find_commit_iter(oid, buf).map(|t| t.0) }) - .map(|res| res.map_err(Into::into).map(|c| c.id)) + .map(|res| res.map_err(|err| Box::new(err) as Box<_>).map(|c| c.id)) .inspect(move |_| progress.inc()), ); (handle, iter) @@ -157,7 +156,7 @@ where .lines() .map(|hex_id| { hex_id - .map_err(Into::into) + .map_err(|err| Box::new(err) as Box<_>) .and_then(|hex_id| ObjectId::from_hex(hex_id.as_bytes()).map_err(Into::into)) }) .inspect(move |_| progress.inc()), @@ -207,7 +206,7 @@ where pack::data::output::count::objects( handle.clone(), input, - progress, + &progress, &interrupt::IS_INTERRUPTED, pack::data::output::count::objects::Options { thread_limit, @@ -217,9 +216,9 @@ where )? } else { pack::data::output::count::objects_unthreaded( - handle.clone(), - input, - progress, + &handle, + &mut input, + &progress, &interrupt::IS_INTERRUPTED, input_object_expansion, )? @@ -236,7 +235,7 @@ where InOrderIter::from(pack::data::output::entry::iter_from_counts( counts, handle, - progress, + Box::new(progress), pack::data::output::entry::iter_from_counts::Options { thread_limit, mode: pack::data::output::entry::iter_from_counts::Mode::PackCopyAndBaseObjects, diff --git a/gitoxide-core/src/pack/explode.rs b/gitoxide-core/src/pack/explode.rs index 5b00f29da0c..f73a54533ad 100644 --- a/gitoxide-core/src/pack/explode.rs +++ b/gitoxide-core/src/pack/explode.rs @@ -97,19 +97,22 @@ enum OutputWriter { } impl gix::odb::Write for OutputWriter { - type Error = Error; - - fn write_buf(&self, kind: object::Kind, from: &[u8]) -> Result { + fn write_buf(&self, kind: object::Kind, from: &[u8]) -> Result { match self { - OutputWriter::Loose(db) => db.write_buf(kind, from).map_err(Into::into), - OutputWriter::Sink(db) => db.write_buf(kind, from).map_err(Into::into), + OutputWriter::Loose(db) => db.write_buf(kind, from), + OutputWriter::Sink(db) => db.write_buf(kind, from), } } - fn write_stream(&self, kind: object::Kind, size: u64, from: impl Read) -> Result { + fn write_stream( + &self, + kind: object::Kind, + size: u64, + from: &mut dyn Read, + ) -> Result { match self { - OutputWriter::Loose(db) => db.write_stream(kind, size, from).map_err(Into::into), - OutputWriter::Sink(db) => db.write_stream(kind, size, from).map_err(Into::into), + OutputWriter::Loose(db) => db.write_stream(kind, size, from), + OutputWriter::Sink(db) => db.write_stream(kind, size, from), } } } @@ -137,7 +140,7 @@ pub fn pack_or_pack_index( pack_path: impl AsRef, object_path: Option>, check: SafetyCheck, - progress: impl NestedProgress, + mut progress: impl NestedProgress + 'static, Context { thread_limit, delete_pack, @@ -178,11 +181,11 @@ pub fn pack_or_pack_index( |_| pack::index::traverse::Algorithm::Lookup, ); - let pack::index::traverse::Outcome { progress, .. } = bundle + let pack::index::traverse::Outcome { .. } = bundle .index .traverse( &bundle.pack, - progress, + &mut progress, &should_interrupt, { let object_path = object_path.map(|p| p.as_ref().to_owned()); @@ -193,7 +196,7 @@ pub fn pack_or_pack_index( let mut read_buf = Vec::new(); move |object_kind, buf, index_entry, progress| { let written_id = out.write_buf(object_kind, buf).map_err(|err| Error::Write { - source: Box::new(err) as Box, + source: err, kind: object_kind, id: index_entry.oid, })?; @@ -213,13 +216,13 @@ pub fn pack_or_pack_index( } if let Some(verifier) = loose_odb.as_ref() { let obj = verifier - .try_find(written_id, &mut read_buf) + .try_find(&written_id, &mut read_buf) .map_err(|err| Error::WrittenFileCorrupt { source: err, id: written_id, })? .ok_or(Error::WrittenFileMissing { id: written_id })?; - obj.verify_checksum(written_id)?; + obj.verify_checksum(&written_id)?; } Ok(()) } diff --git a/gitoxide-core/src/pack/index.rs b/gitoxide-core/src/pack/index.rs index 36a69258497..814f43d0697 100644 --- a/gitoxide-core/src/pack/index.rs +++ b/gitoxide-core/src/pack/index.rs @@ -70,16 +70,12 @@ pub enum PathOrRead { Read(Box), } -pub fn from_pack

( +pub fn from_pack( pack: PathOrRead, directory: Option, - progress: P, + mut progress: impl NestedProgress + 'static, ctx: Context<'static, impl io::Write>, -) -> anyhow::Result<()> -where - P: NestedProgress, - P::SubProgress: 'static, -{ +) -> anyhow::Result<()> { use anyhow::Context; let options = pack::bundle::write::Options { thread_limit: ctx.thread_limit, @@ -94,10 +90,10 @@ where let pack_len = pack.metadata()?.len(); let pack_file = fs::File::open(pack)?; pack::Bundle::write_to_directory_eagerly( - pack_file, + Box::new(pack_file), Some(pack_len), directory, - progress, + &mut progress, ctx.should_interrupt, None, options, @@ -107,7 +103,7 @@ where input, None, directory, - progress, + &mut progress, ctx.should_interrupt, None, options, diff --git a/gitoxide-core/src/pack/multi_index.rs b/gitoxide-core/src/pack/multi_index.rs index b8e0603f480..c49b2723b1f 100644 --- a/gitoxide-core/src/pack/multi_index.rs +++ b/gitoxide-core/src/pack/multi_index.rs @@ -9,17 +9,17 @@ pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; pub fn verify( multi_index_path: PathBuf, - progress: impl NestedProgress, + mut progress: impl NestedProgress + 'static, should_interrupt: &AtomicBool, ) -> anyhow::Result<()> { - gix::odb::pack::multi_index::File::at(multi_index_path)?.verify_integrity_fast(progress, should_interrupt)?; + gix::odb::pack::multi_index::File::at(multi_index_path)?.verify_integrity_fast(&mut progress, should_interrupt)?; Ok(()) } pub fn create( index_paths: Vec, output_path: PathBuf, - progress: impl NestedProgress, + mut progress: impl NestedProgress + 'static, should_interrupt: &AtomicBool, object_hash: gix::hash::Kind, ) -> anyhow::Result<()> { @@ -31,7 +31,7 @@ pub fn create( gix::odb::pack::multi_index::File::write_from_index_paths( index_paths, &mut out, - progress, + &mut progress, should_interrupt, gix::odb::pack::multi_index::write::Options { object_hash }, )?; diff --git a/gitoxide-core/src/pack/receive.rs b/gitoxide-core/src/pack/receive.rs index 9e4c009bb54..fe6de13e697 100644 --- a/gitoxide-core/src/pack/receive.rs +++ b/gitoxide-core/src/pack/receive.rs @@ -130,7 +130,7 @@ mod blocking_io { fn receive_pack( &mut self, input: impl BufRead, - progress: impl NestedProgress, + progress: impl NestedProgress + 'static, refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -156,7 +156,7 @@ mod blocking_io { ) -> anyhow::Result<()> where W: std::io::Write, - P: NestedProgress, + P: NestedProgress + 'static, P::SubProgress: 'static, { let transport = net::connect( @@ -212,7 +212,7 @@ mod async_io { async fn receive_pack( &mut self, input: impl AsyncBufRead + Unpin + 'async_trait, - progress: impl gix::NestedProgress, + progress: impl gix::NestedProgress + 'static, refs: &[Ref], _previous_response: &Response, ) -> io::Result<()> { @@ -367,8 +367,8 @@ fn receive_pack_blocking( mut directory: Option, mut refs_directory: Option, ctx: &mut Context, - input: impl io::BufRead, - progress: impl NestedProgress, + mut input: impl io::BufRead, + mut progress: impl NestedProgress + 'static, refs: &[Ref], ) -> io::Result<()> { let options = pack::bundle::write::Options { @@ -377,9 +377,15 @@ fn receive_pack_blocking( iteration_mode: pack::data::input::Mode::Verify, object_hash: ctx.object_hash, }; - let outcome = - pack::Bundle::write_to_directory(input, directory.take(), progress, &ctx.should_interrupt, None, options) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + let outcome = pack::Bundle::write_to_directory( + &mut input, + directory.take().as_deref(), + &mut progress, + &ctx.should_interrupt, + None, + options, + ) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; if let Some(directory) = refs_directory.take() { write_raw_refs(refs, directory)?; diff --git a/gitoxide-core/src/pack/verify.rs b/gitoxide-core/src/pack/verify.rs index 3b40a13858a..6c9eed25328 100644 --- a/gitoxide-core/src/pack/verify.rs +++ b/gitoxide-core/src/pack/verify.rs @@ -87,7 +87,7 @@ impl pack::cache::DecodeEntry for EitherCache { pub fn pack_or_pack_index( path: impl AsRef, - mut progress: impl NestedProgress, + mut progress: impl NestedProgress + 'static, Context { mut out, mut err, @@ -121,7 +121,7 @@ where let res = match ext { "pack" => { let pack = odb::pack::data::File::at(path, object_hash).with_context(|| "Could not open pack file")?; - pack.verify_checksum(progress.add_child("Sha1 of pack"), should_interrupt) + pack.verify_checksum(&mut progress.add_child("Sha1 of pack"), should_interrupt) .map(|id| (id, None))? } "idx" => { @@ -151,7 +151,7 @@ where thread_limit } }), - progress, + &mut progress, should_interrupt, ) .map(|o| (o.actual_index_checksum, o.pack_traverse_statistics)) @@ -161,7 +161,7 @@ where match path.file_name() { Some(file_name) if file_name == "multi-pack-index" => { let multi_index = gix::odb::pack::multi_index::File::at(path)?; - let res = multi_index.verify_integrity(progress, should_interrupt, gix::odb::pack::index::verify::integrity::Options{ + let res = multi_index.verify_integrity(&mut progress, should_interrupt, gix::odb::pack::index::verify::integrity::Options{ verify_mode: mode, traversal: algorithm.into(), thread_limit, diff --git a/gitoxide-core/src/repository/archive.rs b/gitoxide-core/src/repository/archive.rs index 7ef715638fa..9fdf6fbeace 100644 --- a/gitoxide-core/src/repository/archive.rs +++ b/gitoxide-core/src/repository/archive.rs @@ -34,7 +34,7 @@ pub fn stream( .ok_or_else(|| anyhow!("Adding files requires a worktree directory that contains them"))?, )?; for path in add_paths { - stream.add_entry_from_path(&root, &gix::path::realpath(path)?)?; + stream.add_entry_from_path(&root, &gix::path::realpath(&path)?)?; } } for (path, content) in files { diff --git a/gitoxide-core/src/repository/attributes/query.rs b/gitoxide-core/src/repository/attributes/query.rs index 223edb64462..b2d57563f5f 100644 --- a/gitoxide-core/src/repository/attributes/query.rs +++ b/gitoxide-core/src/repository/attributes/query.rs @@ -8,6 +8,7 @@ pub struct Options { } pub(crate) mod function { + use std::borrow::Cow; use std::{io, path::Path}; use anyhow::{anyhow, bail}; @@ -38,7 +39,10 @@ pub(crate) mod function { match input { PathsOrPatterns::Paths(paths) => { for path in paths { - let is_dir = gix::path::from_bstr(path.as_ref()).metadata().ok().map(|m| m.is_dir()); + let is_dir = gix::path::from_bstr(Cow::Borrowed(path.as_ref())) + .metadata() + .ok() + .map(|m| m.is_dir()); let entry = cache.at_entry(path.as_slice(), is_dir)?; if !entry.matching_attributes(&mut matches) { diff --git a/gitoxide-core/src/repository/clone.rs b/gitoxide-core/src/repository/clone.rs index 96640c69537..fdb2878776b 100644 --- a/gitoxide-core/src/repository/clone.rs +++ b/gitoxide-core/src/repository/clone.rs @@ -11,6 +11,7 @@ pub struct Options { pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; pub(crate) mod function { + use std::borrow::Cow; use std::ffi::OsStr; use anyhow::{bail, Context}; @@ -45,7 +46,7 @@ pub(crate) mod function { let url: gix::Url = url.as_ref().try_into()?; let directory = directory.map_or_else( || { - gix::path::from_bstr(url.path.as_ref()) + gix::path::from_bstr(Cow::Borrowed(url.path.as_ref())) .as_ref() .file_stem() .map(Into::into) diff --git a/gitoxide-core/src/repository/exclude.rs b/gitoxide-core/src/repository/exclude.rs index d42e9fcade4..f3ed2e3595a 100644 --- a/gitoxide-core/src/repository/exclude.rs +++ b/gitoxide-core/src/repository/exclude.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::io; use anyhow::{anyhow, bail}; @@ -37,14 +38,17 @@ pub fn query( let index = repo.index()?; let mut cache = repo.excludes( &index, - Some(gix::ignore::Search::from_overrides(overrides)), + Some(gix::ignore::Search::from_overrides(&mut overrides.into_iter())), Default::default(), )?; match input { PathsOrPatterns::Paths(paths) => { for path in paths { - let is_dir = gix::path::from_bstr(path.as_ref()).metadata().ok().map(|m| m.is_dir()); + let is_dir = gix::path::from_bstr(Cow::Borrowed(path.as_ref())) + .metadata() + .ok() + .map(|m| m.is_dir()); let entry = cache.at_entry(path.as_slice(), is_dir, |oid, buf| repo.objects.find_blob(oid, buf))?; let match_ = entry .matching_exclude_pattern() diff --git a/gitoxide-core/src/repository/index/entries.rs b/gitoxide-core/src/repository/index/entries.rs index f5f988660f1..893f89dda3c 100644 --- a/gitoxide-core/src/repository/index/entries.rs +++ b/gitoxide-core/src/repository/index/entries.rs @@ -158,26 +158,30 @@ pub(crate) mod function { // Note that we intentionally ignore `_case` so that we act like git does, attribute matching case is determined // by the repository, not the pathspec. let entry_is_excluded = pathspec - .pattern_matching_relative_path(entry.path(&index), Some(false), |rela_path, _case, is_dir, out| { - cache - .as_mut() - .map(|(attrs, cache)| { - match last_match { - // The user wants the attributes for display, so the match happened already. - Some(matched) => { - attrs.copy_into(cache.attributes_collection(), out); - matched + .pattern_matching_relative_path( + entry.path(&index), + Some(false), + &mut |rela_path, _case, is_dir, out| { + cache + .as_mut() + .map(|(attrs, cache)| { + match last_match { + // The user wants the attributes for display, so the match happened already. + Some(matched) => { + attrs.copy_into(cache.attributes_collection(), out); + matched + } + // The user doesn't want attributes, so we set the cache position on demand only + None => cache + .at_entry(rela_path, Some(is_dir)) + .ok() + .map(|platform| platform.matching_attributes(out)) + .unwrap_or_default(), } - // The user doesn't want attributes, so we set the cache position on demand only - None => cache - .at_entry(rela_path, Some(is_dir)) - .ok() - .map(|platform| platform.matching_attributes(out)) - .unwrap_or_default(), - } - }) - .unwrap_or_default() - }) + }) + .unwrap_or_default() + }, + ) .map_or(true, |m| m.is_excluded()); let entry_is_submodule = entry.mode.is_submodule(); diff --git a/gitoxide-core/src/repository/verify.rs b/gitoxide-core/src/repository/verify.rs index df5a74c5192..3f033fae5e4 100644 --- a/gitoxide-core/src/repository/verify.rs +++ b/gitoxide-core/src/repository/verify.rs @@ -19,7 +19,7 @@ pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; pub fn integrity( repo: gix::Repository, mut out: impl std::io::Write, - progress: impl gix::NestedProgress, + mut progress: impl gix::NestedProgress + 'static, should_interrupt: &AtomicBool, Context { output_statistics, @@ -30,7 +30,7 @@ pub fn integrity( ) -> anyhow::Result<()> { #[cfg_attr(not(feature = "serde"), allow(unused))] let outcome = repo.objects.store_ref().verify_integrity( - progress, + &mut progress, should_interrupt, gix::odb::pack::index::verify::integrity::Options { verify_mode, @@ -48,9 +48,7 @@ pub fn integrity( let objects = repo.objects; move |oid, buf: &mut Vec| objects.find_tree_iter(oid, buf).ok() })?; - outcome - .progress - .info(format!("Index at '{}' OK", index.path().display())); + progress.info(format!("Index at '{}' OK", index.path().display())); } match output_statistics { Some(OutputFormat::Human) => writeln!(out, "Human output is currently unsupported, use JSON instead")?, diff --git a/gix-actor/src/identity.rs b/gix-actor/src/identity.rs index 9507afdc297..e6d8fcb520f 100644 --- a/gix-actor/src/identity.rs +++ b/gix-actor/src/identity.rs @@ -35,14 +35,14 @@ mod write { /// Output impl Identity { /// Serialize this instance to `out` in the git serialization format for signatures (but without timestamp). - pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { self.to_ref().write_to(out) } } impl<'a> IdentityRef<'a> { /// Serialize this instance to `out` in the git serialization format for signatures (but without timestamp). - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { out.write_all(validated_token(self.name)?)?; out.write_all(b" ")?; out.write_all(b"<")?; diff --git a/gix-actor/src/signature/mod.rs b/gix-actor/src/signature/mod.rs index cb91bd8eb9f..057d4293e7d 100644 --- a/gix-actor/src/signature/mod.rs +++ b/gix-actor/src/signature/mod.rs @@ -95,7 +95,7 @@ pub(crate) mod write { /// Output impl Signature { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { self.to_ref().write_to(out) } /// Computes the number of bytes necessary to serialize this signature @@ -106,7 +106,7 @@ pub(crate) mod write { impl<'a> SignatureRef<'a> { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { out.write_all(validated_token(self.name)?)?; out.write_all(b" ")?; out.write_all(b"<")?; diff --git a/gix-actor/tests/signature/mod.rs b/gix-actor/tests/signature/mod.rs index e0c7e663d2e..496fb54ae54 100644 --- a/gix-actor/tests/signature/mod.rs +++ b/gix-actor/tests/signature/mod.rs @@ -11,7 +11,7 @@ mod write_to { time: default_time(), }; assert_eq!( - format!("{:?}", signature.write_to(Vec::new())), + format!("{:?}", signature.write_to(&mut Vec::new())), "Err(Custom { kind: Other, error: IllegalCharacter })" ); } @@ -24,7 +24,7 @@ mod write_to { time: default_time(), }; assert_eq!( - format!("{:?}", signature.write_to(Vec::new())), + format!("{:?}", signature.write_to(&mut Vec::new())), "Err(Custom { kind: Other, error: IllegalCharacter })" ); } @@ -37,7 +37,7 @@ mod write_to { time: default_time(), }; assert_eq!( - format!("{:?}", signature.write_to(Vec::new())), + format!("{:?}", signature.write_to(&mut Vec::new())), "Err(Custom { kind: Other, error: IllegalCharacter })" ); } diff --git a/gix-attributes/src/search/attributes.rs b/gix-attributes/src/search/attributes.rs index 8eb66621366..2b48d1ed3be 100644 --- a/gix-attributes/src/search/attributes.rs +++ b/gix-attributes/src/search/attributes.rs @@ -27,14 +27,14 @@ impl Search { let mut group = Self::default(); group.add_patterns_buffer( b"[attr]binary -diff -merge -text", - "[builtin]", + "[builtin]".into(), None, collection, true, /* allow macros */ ); for path in files.into_iter() { - group.add_patterns_file(path, true, None, buf, collection, true /* allow macros */)?; + group.add_patterns_file(path.into(), true, None, buf, collection, true /* allow macros */)?; } Ok(group) } @@ -49,7 +49,7 @@ impl Search { /// Returns `true` if the file was added, or `false` if it didn't exist. pub fn add_patterns_file( &mut self, - source: impl Into, + source: PathBuf, follow_symlinks: bool, root: Option<&Path>, buf: &mut Vec, @@ -75,7 +75,7 @@ impl Search { pub fn add_patterns_buffer( &mut self, bytes: &[u8], - source: impl Into, + source: PathBuf, root: Option<&Path>, collection: &mut MetadataCollection, allow_macros: bool, @@ -99,14 +99,13 @@ impl Search { impl Search { /// Match `relative_path`, a path relative to the repository, while respective `case`-sensitivity and write them to `out` /// Return `true` if at least one pattern matched. - pub fn pattern_matching_relative_path<'a, 'b>( - &'a self, - relative_path: impl Into<&'b BStr>, + pub fn pattern_matching_relative_path( + &self, + relative_path: &BStr, case: gix_glob::pattern::Case, is_dir: Option, out: &mut Outcome, ) -> bool { - let relative_path = relative_path.into(); let basename_pos = relative_path.rfind(b"/").map(|p| p + 1); let mut has_match = false; self.patterns.iter().rev().any(|pl| { diff --git a/gix-attributes/src/search/outcome.rs b/gix-attributes/src/search/outcome.rs index 409be393833..6f724a407ff 100644 --- a/gix-attributes/src/search/outcome.rs +++ b/gix-attributes/src/search/outcome.rs @@ -45,12 +45,19 @@ impl Outcome { &mut self, collection: &MetadataCollection, attribute_names: impl IntoIterator>>, + ) { + self.initialize_with_selection_inner(collection, &mut attribute_names.into_iter().map(Into::into)) + } + + fn initialize_with_selection_inner( + &mut self, + collection: &MetadataCollection, + attribute_names: &mut dyn Iterator>, ) { self.initialize(collection); self.selected.clear(); - self.selected.extend(attribute_names.into_iter().map(|name| { - let name = name.into(); + self.selected.extend(attribute_names.map(|name| { ( name.to_owned(), collection.name_to_meta.get(name.as_str()).map(|meta| meta.id), diff --git a/gix-attributes/tests/search/mod.rs b/gix-attributes/tests/search/mod.rs index b8fbaf83072..36e6286c8ed 100644 --- a/gix-attributes/tests/search/mod.rs +++ b/gix-attributes/tests/search/mod.rs @@ -50,7 +50,7 @@ mod specials { ); let mut out = Outcome::default(); out.initialize(&collection); - search.pattern_matching_relative_path(path, case, None, &mut out) + search.pattern_matching_relative_path(path.into(), case, None, &mut out) } fn searchi(pattern: &str, path: &str, rela_containing_dir: Option<&str>) -> bool { @@ -66,7 +66,7 @@ fn baseline() -> crate::Result { let mut buf = Vec::new(); // Due to the way our setup differs from gits dynamic stack (which involves trying to read files from disk // by path) we can only test one case baseline, so we require multiple platforms (or filesystems) to run this. - let case = if gix_fs::Capabilities::probe("../.git").ignore_case { + let case = if gix_fs::Capabilities::probe("../.git".as_ref()).ignore_case { Case::Fold } else { Case::Sensitive @@ -307,7 +307,11 @@ mod baseline { let mut buf = Vec::new(); let mut collection = MetadataCollection::default(); - let group = gix_attributes::Search::new_globals([base.join("user.attributes")], &mut buf, &mut collection)?; + let group = gix_attributes::Search::new_globals( + &mut [base.join("user.attributes")].into_iter(), + &mut buf, + &mut collection, + )?; Ok((group, collection, base, input)) } diff --git a/gix-commitgraph/src/file/access.rs b/gix-commitgraph/src/file/access.rs index d3c32d8bb0e..79a40d75dbf 100644 --- a/gix-commitgraph/src/file/access.rs +++ b/gix-commitgraph/src/file/access.rs @@ -74,7 +74,10 @@ impl File { /// Translate the given object hash to its position within this file, if present. // copied from gix-odb/src/pack/index/ext pub fn lookup(&self, id: impl AsRef) -> Option { - let id = id.as_ref(); + self.lookup_inner(id.as_ref()) + } + + fn lookup_inner(&self, id: &gix_hash::oid) -> Option { let first_byte = usize::from(id.first_byte()); let mut upper_bound = self.fan[first_byte]; let mut lower_bound = if first_byte != 0 { self.fan[first_byte - 1] } else { 0 }; diff --git a/gix-commitgraph/src/file/verify.rs b/gix-commitgraph/src/file/verify.rs index 91da92c635e..c91f6b4d281 100644 --- a/gix-commitgraph/src/file/verify.rs +++ b/gix-commitgraph/src/file/verify.rs @@ -160,8 +160,7 @@ impl File { /// If the given path's filename matches "graph-{hash}.graph", check that `hash` matches the /// expected hash. -fn verify_split_chain_filename_hash(path: impl AsRef, expected: &gix_hash::oid) -> Result<(), String> { - let path = path.as_ref(); +fn verify_split_chain_filename_hash(path: &Path, expected: &gix_hash::oid) -> Result<(), String> { path.file_name() .and_then(std::ffi::OsStr::to_str) .and_then(|filename| filename.strip_suffix(".graph")) diff --git a/gix-commitgraph/src/init.rs b/gix-commitgraph/src/init.rs index f964aade029..0b03ba9462d 100644 --- a/gix-commitgraph/src/init.rs +++ b/gix-commitgraph/src/init.rs @@ -41,13 +41,13 @@ pub enum Error { /// Instantiate a `Graph` from various sources. impl Graph { /// Instantiate a commit graph from `path` which may be a directory containing graph files or the graph file itself. - pub fn at(path: impl AsRef) -> Result { - Self::try_from(path.as_ref()) + pub fn at(path: &Path) -> Result { + Self::try_from(path) } /// Instantiate a commit graph from the directory containing all of its files. - pub fn from_commit_graphs_dir(path: impl AsRef) -> Result { - let commit_graphs_dir = path.as_ref(); + pub fn from_commit_graphs_dir(path: &Path) -> Result { + let commit_graphs_dir = path; let chain_file_path = commit_graphs_dir.join("commit-graph-chain"); let chain_file = std::fs::File::open(&chain_file_path).map_err(|e| Error::Io { err: e, @@ -70,8 +70,7 @@ impl Graph { /// Instantiate a commit graph from a `.git/objects/info/commit-graph` or /// `.git/objects/info/commit-graphs/graph-*.graph` file. - pub fn from_file(path: impl AsRef) -> Result { - let path = path.as_ref(); + pub fn from_file(path: &Path) -> Result { let file = File::at(path).map_err(|e| Error::File { err: e, path: path.to_owned(), @@ -80,9 +79,9 @@ impl Graph { } /// Instantiate a commit graph from an `.git/objects/info` directory. - pub fn from_info_dir(info_dir: impl AsRef) -> Result { - Self::from_file(info_dir.as_ref().join("commit-graph")) - .or_else(|_| Self::from_commit_graphs_dir(info_dir.as_ref().join("commit-graphs"))) + pub fn from_info_dir(info_dir: &Path) -> Result { + Self::from_file(&info_dir.join("commit-graph")) + .or_else(|_| Self::from_commit_graphs_dir(&info_dir.join("commit-graphs"))) } /// Create a new commit graph from a list of `files`. diff --git a/gix-commitgraph/src/lib.rs b/gix-commitgraph/src/lib.rs index 231c11c6fb0..a247ccd87de 100644 --- a/gix-commitgraph/src/lib.rs +++ b/gix-commitgraph/src/lib.rs @@ -45,7 +45,7 @@ pub struct Graph { /// Instantiate a commit graph from an `.git/objects/info` directory, or one of the various commit-graph files. pub fn at(path: impl AsRef) -> Result { - Graph::at(path) + Graph::at(path.as_ref()) } mod access; diff --git a/gix-commitgraph/tests/commitgraph.rs b/gix-commitgraph/tests/commitgraph.rs index 20d20dee1ee..94568fe5cfa 100644 --- a/gix-commitgraph/tests/commitgraph.rs +++ b/gix-commitgraph/tests/commitgraph.rs @@ -80,7 +80,8 @@ pub fn graph_and_expected_named( .expect("script succeeds all the time") .join(name); let expected = inspect_refs(&repo_dir, refs); - let cg = Graph::from_info_dir(repo_dir.join(".git").join("objects").join("info")).expect("graph present and valid"); + let cg = + Graph::from_info_dir(&repo_dir.join(".git").join("objects").join("info")).expect("graph present and valid"); (cg, expected) } diff --git a/gix-config/fuzz/fuzz_targets/parse.rs b/gix-config/fuzz/fuzz_targets/parse.rs index a065ad75950..34a12ceeb02 100644 --- a/gix-config/fuzz/fuzz_targets/parse.rs +++ b/gix-config/fuzz/fuzz_targets/parse.rs @@ -4,5 +4,5 @@ use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { // Don't name this _; Rust may optimize it out. - let _a = gix_config::parse::from_bytes(data, |_e| ()); + let _a = gix_config::parse::from_bytes(data, &mut |_e| ()); }); diff --git a/gix-config/src/file/access/comfort.rs b/gix-config/src/file/access/comfort.rs index 5ad0e6186b7..ed62e779269 100644 --- a/gix-config/src/file/access/comfort.rs +++ b/gix-config/src/file/access/comfort.rs @@ -31,7 +31,8 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Option> { - self.raw_value_filter(section_name, subsection_name, key, filter).ok() + self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok() } /// Like [`string_filter()`][File::string_filter()], but suitable for statically known `key`s like `remote.origin.url`. @@ -40,7 +41,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.raw_value_filter(key.section_name, key.subsection_name, key.value_name, filter) .ok() } @@ -78,7 +79,7 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Option> { - self.raw_value_filter(section_name, subsection_name, key, filter) + self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) .ok() .map(crate::Path::from) } @@ -89,7 +90,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.path_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -141,7 +142,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.boolean_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -168,7 +169,9 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Option> { - let int = self.raw_value_filter(section_name, subsection_name, key, filter).ok()?; + let int = self + .raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok()?; Some(crate::Integer::try_from(int.as_ref()).and_then(|b| { b.to_decimal() .ok_or_else(|| value::Error::new("Integer overflow", int.into_owned())) @@ -181,7 +184,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.integer_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -192,12 +195,13 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, key: impl AsRef, ) -> Option>> { - self.raw_values(section_name, subsection_name, key).ok() + self.raw_values(section_name.as_ref(), subsection_name, key.as_ref()) + .ok() } /// Like [`strings()`][File::strings()], but suitable for statically known `key`s like `remote.origin.url`. pub fn strings_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.strings(key.section_name, key.subsection_name, key.value_name) } @@ -209,7 +213,8 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Option>> { - self.raw_values_filter(section_name, subsection_name, key, filter).ok() + self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) + .ok() } /// Like [`strings_filter()`][File::strings_filter()], but suitable for statically known `key`s like `remote.origin.url`. @@ -218,7 +223,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.strings_filter(key.section_name, key.subsection_name, key.value_name, filter) } @@ -247,7 +252,7 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Option, value::Error>> { - self.raw_values_filter(section_name, subsection_name, key, filter) + self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter) .ok() .map(|values| { values @@ -268,7 +273,7 @@ impl<'event> File<'event> { key: impl Into<&'a BStr>, filter: &mut MetadataFilter, ) -> Option, value::Error>> { - let key = crate::parse::key(key)?; + let key = crate::parse::key(key.into())?; self.integers_filter(key.section_name, key.subsection_name, key.value_name, filter) } } diff --git a/gix-config/src/file/access/mutate.rs b/gix-config/src/file/access/mutate.rs index 5237b3794bb..4844a34f4d1 100644 --- a/gix-config/src/file/access/mutate.rs +++ b/gix-config/src/file/access/mutate.rs @@ -17,9 +17,17 @@ impl<'event> File<'event> { &'a mut self, name: impl AsRef, subsection_name: Option<&BStr>, + ) -> Result, lookup::existing::Error> { + self.section_mut_inner(name.as_ref(), subsection_name) + } + + fn section_mut_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, ) -> Result, lookup::existing::Error> { let id = self - .section_ids_by_name_and_subname(name.as_ref(), subsection_name)? + .section_ids_by_name_and_subname(name, subsection_name)? .next_back() .expect("BUG: Section lookup vec was empty"); let nl = self.detect_newline_style_smallvec(); @@ -64,7 +72,15 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, filter: &mut MetadataFilter, ) -> Result, section::header::Error> { - let name = name.as_ref(); + self.section_mut_or_create_new_filter_inner(name.as_ref(), subsection_name, filter) + } + + fn section_mut_or_create_new_filter_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, + ) -> Result, section::header::Error> { match self .section_ids_by_name_and_subname(name.as_ref(), subsection_name) .ok() @@ -95,9 +111,18 @@ impl<'event> File<'event> { name: impl AsRef, subsection_name: Option<&BStr>, filter: &mut MetadataFilter, + ) -> Result>, lookup::existing::Error> { + self.section_mut_filter_inner(name.as_ref(), subsection_name, filter) + } + + fn section_mut_filter_inner<'a>( + &'a mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, ) -> Result>, lookup::existing::Error> { let id = self - .section_ids_by_name_and_subname(name.as_ref(), subsection_name)? + .section_ids_by_name_and_subname(name, subsection_name)? .rev() .find(|id| { let s = &self.sections[id]; @@ -158,6 +183,14 @@ impl<'event> File<'event> { &mut self, name: impl Into>, subsection: impl Into>>, + ) -> Result, section::header::Error> { + self.new_section_inner(name.into(), subsection.into()) + } + + fn new_section_inner( + &mut self, + name: Cow<'event, str>, + subsection: Option>, ) -> Result, section::header::Error> { let id = self.push_section_internal(file::Section::new(name, subsection, OwnShared::clone(&self.meta))?); let nl = self.detect_newline_style_smallvec(); @@ -205,11 +238,11 @@ impl<'event> File<'event> { /// ``` pub fn remove_section<'a>( &mut self, - name: &str, + name: impl AsRef, subsection_name: impl Into>, ) -> Option> { let id = self - .section_ids_by_name_and_subname(name, subsection_name.into()) + .section_ids_by_name_and_subname(name.as_ref(), subsection_name.into()) .ok()? .next_back()?; self.remove_section_by_id(id) @@ -254,12 +287,21 @@ impl<'event> File<'event> { /// later sections with the same name have precedent over earlier ones. pub fn remove_section_filter<'a>( &mut self, - name: &str, + name: impl AsRef, subsection_name: impl Into>, filter: &mut MetadataFilter, + ) -> Option> { + self.remove_section_filter_inner(name.as_ref(), subsection_name.into(), filter) + } + + fn remove_section_filter_inner( + &mut self, + name: &str, + subsection_name: Option<&BStr>, + filter: &mut MetadataFilter, ) -> Option> { let id = self - .section_ids_by_name_and_subname(name, subsection_name.into()) + .section_ids_by_name_and_subname(name, subsection_name) .ok()? .rev() .find(|id| filter(self.sections.get(id).expect("each id has a section").meta()))?; diff --git a/gix-config/src/file/access/raw.rs b/gix-config/src/file/access/raw.rs index 6fef6c9ed40..3736bf3a286 100644 --- a/gix-config/src/file/access/raw.rs +++ b/gix-config/src/file/access/raw.rs @@ -40,8 +40,17 @@ impl<'event> File<'event> { key: impl AsRef, filter: &mut MetadataFilter, ) -> Result, lookup::existing::Error> { - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; - let key = key.as_ref(); + self.raw_value_filter_inner(section_name.as_ref(), subsection_name, key.as_ref(), filter) + } + + fn raw_value_filter_inner( + &self, + section_name: &str, + subsection_name: Option<&BStr>, + key: &str, + filter: &mut MetadataFilter, + ) -> Result, lookup::existing::Error> { + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; for section_id in section_ids.rev() { let section = self.sections.get(§ion_id).expect("known section id"); if !filter(section.meta()) { @@ -80,9 +89,19 @@ impl<'event> File<'event> { subsection_name: Option<&'lookup BStr>, key: &'lookup str, filter: &mut MetadataFilter, + ) -> Result, lookup::existing::Error> { + self.raw_value_mut_filter_inner(section_name.as_ref(), subsection_name, key, filter) + } + + fn raw_value_mut_filter_inner<'lookup>( + &mut self, + section_name: &str, + subsection_name: Option<&'lookup BStr>, + key: &'lookup str, + filter: &mut MetadataFilter, ) -> Result, lookup::existing::Error> { let mut section_ids = self - .section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)? + .section_ids_by_name_and_subname(section_name, subsection_name)? .rev(); let key = section::Key(Cow::::Borrowed(key.into())); @@ -190,10 +209,19 @@ impl<'event> File<'event> { subsection_name: Option<&BStr>, key: impl AsRef, filter: &mut MetadataFilter, + ) -> Result>, lookup::existing::Error> { + self.raw_values_filter_inner(section_name.as_ref(), subsection_name, key.as_ref(), filter) + } + + fn raw_values_filter_inner( + &self, + section_name: &str, + subsection_name: Option<&BStr>, + key: &str, + filter: &mut MetadataFilter, ) -> Result>, lookup::existing::Error> { let mut values = Vec::new(); - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; - let key = key.as_ref(); + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; for section_id in section_ids { let section = self.sections.get(§ion_id).expect("known section id"); if !filter(section.meta()) { @@ -277,7 +305,17 @@ impl<'event> File<'event> { key: &'lookup str, filter: &mut MetadataFilter, ) -> Result, lookup::existing::Error> { - let section_ids = self.section_ids_by_name_and_subname(section_name.as_ref(), subsection_name)?; + self.raw_values_mut_filter_inner(section_name.as_ref(), subsection_name, key, filter) + } + + fn raw_values_mut_filter_inner<'lookup>( + &mut self, + section_name: &str, + subsection_name: Option<&'lookup BStr>, + key: &'lookup str, + filter: &mut MetadataFilter, + ) -> Result, lookup::existing::Error> { + let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?; let key = section::Key(Cow::::Borrowed(key.into())); let mut offsets = HashMap::new(); @@ -432,7 +470,7 @@ impl<'event> File<'event> { section::key::Error: From, { let mut section = self.section_mut_or_create_new_filter(section_name, subsection_name, filter)?; - Ok(section.set(key.try_into().map_err(section::key::Error::from)?, new_value)) + Ok(section.set(key.try_into().map_err(section::key::Error::from)?, new_value.into())) } /// Sets a multivar in a given section, optional subsection, and key value. diff --git a/gix-config/src/file/access/read_only.rs b/gix-config/src/file/access/read_only.rs index d5fd192bb7b..eb1071fe2e1 100644 --- a/gix-config/src/file/access/read_only.rs +++ b/gix-config/src/file/access/read_only.rs @@ -131,7 +131,7 @@ impl<'event> File<'event> { /// Returns the last found immutable section with a given `name` and optional `subsection_name`. pub fn section( &self, - name: impl AsRef, + name: &str, subsection_name: Option<&BStr>, ) -> Result<&file::Section<'event>, lookup::existing::Error> { self.section_filter(name, subsection_name, &mut |_| true)? @@ -140,10 +140,7 @@ impl<'event> File<'event> { /// Returns the last found immutable section with a given `key`, identifying the name and subsection name like `core` /// or `remote.origin`. - pub fn section_by_key<'a>( - &self, - key: impl Into<&'a BStr>, - ) -> Result<&file::Section<'event>, lookup::existing::Error> { + pub fn section_by_key(&self, key: &BStr) -> Result<&file::Section<'event>, lookup::existing::Error> { let key = crate::parse::section::unvalidated::Key::parse(key).ok_or(lookup::existing::Error::KeyMissing)?; self.section(key.section_name, key.subsection_name) } @@ -154,7 +151,7 @@ impl<'event> File<'event> { /// is returned. pub fn section_filter<'a>( &'a self, - name: impl AsRef, + name: &str, subsection_name: Option<&BStr>, filter: &mut MetadataFilter, ) -> Result>, lookup::existing::Error> { @@ -171,9 +168,9 @@ impl<'event> File<'event> { } /// Like [`section_filter()`][File::section_filter()], but identifies the section with `key` like `core` or `remote.origin`. - pub fn section_filter_by_key<'a, 'b>( + pub fn section_filter_by_key<'a>( &'a self, - key: impl Into<&'b BStr>, + key: &BStr, filter: &mut MetadataFilter, ) -> Result>, lookup::existing::Error> { let key = crate::parse::section::unvalidated::Key::parse(key).ok_or(lookup::existing::Error::KeyMissing)?; diff --git a/gix-config/src/file/init/comfort.rs b/gix-config/src/file/init/comfort.rs index f8e624c731b..4a5a1c68b25 100644 --- a/gix-config/src/file/init/comfort.rs +++ b/gix-config/src/file/init/comfort.rs @@ -82,16 +82,16 @@ impl File<'static> { /// /// Includes will be resolved within limits as some information like the git installation directory is missing to interpolate /// paths with as well as git repository information like the branch name. - pub fn from_git_dir(dir: impl Into) -> Result, from_git_dir::Error> { + pub fn from_git_dir(dir: std::path::PathBuf) -> Result, from_git_dir::Error> { let (mut local, git_dir) = { let source = Source::Local; - let mut path = dir.into(); + let mut path = dir; path.push( source .storage_location(&mut gix_path::env::var) .expect("location available for local"), ); - let local = Self::from_path_no_includes(&path, source)?; + let local = Self::from_path_no_includes(path.clone(), source)?; path.pop(); (local, path) }; diff --git a/gix-config/src/file/init/from_paths.rs b/gix-config/src/file/init/from_paths.rs index ea209cefc4c..5d092f88a7c 100644 --- a/gix-config/src/file/init/from_paths.rs +++ b/gix-config/src/file/init/from_paths.rs @@ -23,8 +23,7 @@ impl File<'static> { /// Load the single file at `path` with `source` without following include directives. /// /// Note that the path will be checked for ownership to derive trust. - pub fn from_path_no_includes(path: impl Into, source: crate::Source) -> Result { - let path = path.into(); + pub fn from_path_no_includes(path: std::path::PathBuf, source: crate::Source) -> Result { let trust = match gix_sec::Trust::from_path_ownership(&path) { Ok(t) => t, Err(err) => return Err(Error::Io { source: err, path }), @@ -60,7 +59,12 @@ impl File<'static> { ) -> Result, Error> { let mut buf = Vec::with_capacity(512); let err_on_nonexisting_paths = true; - Self::from_paths_metadata_buf(path_meta, &mut buf, err_on_nonexisting_paths, options) + Self::from_paths_metadata_buf( + &mut path_meta.into_iter().map(Into::into), + &mut buf, + err_on_nonexisting_paths, + options, + ) } /// Like [`from_paths_metadata()`][Self::from_paths_metadata()], but will use `buf` to temporarily store the config file @@ -68,17 +72,14 @@ impl File<'static> { /// /// If `err_on_nonexisting_paths` is false, instead of aborting with error, we will continue to the next path instead. pub fn from_paths_metadata_buf( - path_meta: impl IntoIterator>, + path_meta: &mut dyn Iterator, buf: &mut Vec, err_on_non_existing_paths: bool, options: Options<'_>, ) -> Result, Error> { let mut target = None; let mut seen = BTreeSet::default(); - for (path, mut meta) in path_meta.into_iter().filter_map(|meta| { - let mut meta = meta.into(); - meta.path.take().map(|p| (p, meta)) - }) { + for (path, mut meta) in path_meta.filter_map(|mut meta| meta.path.take().map(|p| (p, meta))) { if !seen.insert(path.clone()) { continue; } diff --git a/gix-config/src/file/mutable/section.rs b/gix-config/src/file/mutable/section.rs index f13b87e483a..336ccad2d7e 100644 --- a/gix-config/src/file/mutable/section.rs +++ b/gix-config/src/file/mutable/section.rs @@ -123,10 +123,10 @@ impl<'a, 'event> SectionMut<'a, 'event> { /// Sets the last key value pair if it exists, or adds the new value. /// Returns the previous value if it replaced a value, or None if it adds /// the value. - pub fn set<'b>(&mut self, key: Key<'event>, value: impl Into<&'b BStr>) -> Option> { + pub fn set(&mut self, key: Key<'event>, value: &BStr) -> Option> { match self.key_and_value_range_by(&key) { None => { - self.push(key, Some(value.into())); + self.push(key, Some(value)); None } Some((key_range, value_range)) => { @@ -136,15 +136,15 @@ impl<'a, 'event> SectionMut<'a, 'event> { self.section .body .0 - .insert(range_start, Event::Value(escape_value(value.into()).into())); + .insert(range_start, Event::Value(escape_value(value).into())); Some(ret) } } } /// Removes the latest value by key and returns it, if it exists. - pub fn remove(&mut self, key: impl AsRef) -> Option> { - let key = Key::from_str_unchecked(key.as_ref()); + pub fn remove(&mut self, key: &str) -> Option> { + let key = Key::from_str_unchecked(key); let (key_range, _value_range) = self.key_and_value_range_by(&key)?; Some(self.remove_internal(key_range, true)) } diff --git a/gix-config/src/file/section/body.rs b/gix-config/src/file/section/body.rs index 694de18bd91..1bc12725c6b 100644 --- a/gix-config/src/file/section/body.rs +++ b/gix-config/src/file/section/body.rs @@ -18,14 +18,14 @@ impl<'event> Body<'event> { /// Note that we consider values without key separator `=` non-existing. #[must_use] pub fn value(&self, key: impl AsRef) -> Option> { - self.value_implicit(key).flatten() + self.value_implicit(key.as_ref()).flatten() } /// Retrieves the last matching value in a section with the given key, if present, and indicates an implicit value with `Some(None)`, /// and a non-existing one as `None` #[must_use] - pub fn value_implicit(&self, key: impl AsRef) -> Option>> { - let key = Key::from_str_unchecked(key.as_ref()); + pub fn value_implicit(&self, key: &str) -> Option>> { + let key = Key::from_str_unchecked(key); let (_key_range, range) = self.key_and_value_range_by(&key)?; let range = match range { None => return Some(None), @@ -54,8 +54,8 @@ impl<'event> Body<'event> { /// Retrieves all values that have the provided key name. This may return /// an empty vec, which implies there were no values with the provided key. #[must_use] - pub fn values(&self, key: impl AsRef) -> Vec> { - let key = &Key::from_str_unchecked(key.as_ref()); + pub fn values(&self, key: &str) -> Vec> { + let key = &Key::from_str_unchecked(key); let mut values = Vec::new(); let mut expect_value = false; let mut concatenated_value = BString::default(); @@ -92,8 +92,8 @@ impl<'event> Body<'event> { /// Returns true if the section contains the provided key. #[must_use] - pub fn contains_key(&self, key: impl AsRef) -> bool { - let key = &Key::from_str_unchecked(key.as_ref()); + pub fn contains_key(&self, key: &str) -> bool { + let key = &Key::from_str_unchecked(key); self.0.iter().any(|e| { matches!(e, Event::SectionKey(k) if k == key diff --git a/gix-config/src/file/section/mod.rs b/gix-config/src/file/section/mod.rs index f73405960d0..f07a145e3d4 100644 --- a/gix-config/src/file/section/mod.rs +++ b/gix-config/src/file/section/mod.rs @@ -74,7 +74,7 @@ impl<'a> Section<'a> { /// Stream ourselves to the given `out`, in order to reproduce this section mostly losslessly /// as it was parsed. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> { self.header.write_to(&mut out)?; if self.body.0.is_empty() { diff --git a/gix-config/src/file/write.rs b/gix-config/src/file/write.rs index b4cd9c48fc6..772054f9529 100644 --- a/gix-config/src/file/write.rs +++ b/gix-config/src/file/write.rs @@ -17,8 +17,8 @@ impl File<'_> { /// as it was parsed, while writing only sections for which `filter` returns true. pub fn write_to_filter( &self, - mut out: impl std::io::Write, - mut filter: impl FnMut(&Section<'_>) -> bool, + mut out: &mut dyn std::io::Write, + mut filter: &mut dyn FnMut(&Section<'_>) -> bool, ) -> std::io::Result<()> { let nl = self.detect_newline_style(); @@ -65,8 +65,8 @@ impl File<'_> { /// Stream ourselves to the given `out`, in order to reproduce this file mostly losslessly /// as it was parsed. - pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { - self.write_to_filter(out, |_| true) + pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> { + self.write_to_filter(out, &mut |_| true) } } diff --git a/gix-config/src/parse/event.rs b/gix-config/src/parse/event.rs index b7b96934d04..f528e2077d6 100644 --- a/gix-config/src/parse/event.rs +++ b/gix-config/src/parse/event.rs @@ -33,7 +33,7 @@ impl Event<'_> { /// Stream ourselves to the given `out`, in order to reproduce this event mostly losslessly /// as it was parsed. - pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> { match self { Self::ValueNotDone(e) => { out.write_all(e.as_ref())?; diff --git a/gix-config/src/parse/events.rs b/gix-config/src/parse/events.rs index 1a1287d642b..f3f5275005a 100644 --- a/gix-config/src/parse/events.rs +++ b/gix-config/src/parse/events.rs @@ -229,7 +229,7 @@ impl Events<'static> { input: &'a [u8], filter: Option) -> bool>, ) -> Result, parse::Error> { - from_bytes(input, |e| e.to_owned(), filter) + from_bytes(input, &|e| e.to_owned(), filter) } } @@ -241,7 +241,7 @@ impl<'a> Events<'a> { /// /// Use `filter` to only include those events for which it returns true. pub fn from_bytes(input: &'a [u8], filter: Option) -> bool>) -> Result, parse::Error> { - from_bytes(input, std::convert::identity, filter) + from_bytes(input, &std::convert::identity, filter) } /// Attempt to zero-copy parse the provided `input` string. @@ -288,14 +288,14 @@ impl<'a> TryFrom<&'a [u8]> for Events<'a> { fn from_bytes<'a, 'b>( input: &'a [u8], - convert: impl Fn(Event<'a>) -> Event<'b>, + convert: &dyn Fn(Event<'a>) -> Event<'b>, filter: Option) -> bool>, ) -> Result, parse::Error> { let mut header = None; let mut events = section::Events::default(); let mut frontmatter = FrontMatterEvents::default(); let mut sections = Vec::new(); - parse::from_bytes(input, |e: Event<'_>| match e { + parse::from_bytes(input, &mut |e: Event<'_>| match e { Event::SectionHeader(next_header) => { match header.take() { None => { diff --git a/gix-config/src/parse/key.rs b/gix-config/src/parse/key.rs index b0e0376be2a..0ebb09e5f51 100644 --- a/gix-config/src/parse/key.rs +++ b/gix-config/src/parse/key.rs @@ -14,8 +14,7 @@ pub struct Key<'a> { /// Parse `input` like `core.bare` or `remote.origin.url` as a `Key` to make its fields available, /// or `None` if there were not at least 2 tokens separated by `.`. /// Note that `input` isn't validated, and is `str` as ascii is a subset of UTF-8 which is required for any valid keys. -pub fn parse_unvalidated<'a>(input: impl Into<&'a BStr>) -> Option> { - let input = input.into(); +pub fn parse_unvalidated(input: &BStr) -> Option> { let mut tokens = input.splitn(2, |b| *b == b'.'); let section_name = tokens.next()?; let subsection_or_key = tokens.next()?; diff --git a/gix-config/src/parse/nom/mod.rs b/gix-config/src/parse/nom/mod.rs index 1ae2f8593d1..3ae45618dc2 100644 --- a/gix-config/src/parse/nom/mod.rs +++ b/gix-config/src/parse/nom/mod.rs @@ -12,7 +12,7 @@ use winnow::{ use crate::parse::{error::ParseNode, section, Comment, Error, Event}; /// Attempt to zero-copy parse the provided bytes, passing results to `dispatch`. -pub fn from_bytes<'i>(mut input: &'i [u8], mut dispatch: impl FnMut(Event<'i>)) -> Result<(), Error> { +pub fn from_bytes<'i>(mut input: &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> Result<(), Error> { let start = input.checkpoint(); let bom = unicode_bom::Bom::from(input); @@ -46,7 +46,7 @@ pub fn from_bytes<'i>(mut input: &'i [u8], mut dispatch: impl FnMut(Event<'i>)) let mut node = ParseNode::SectionHeader; - let res = repeat(1.., |i: &mut &'i [u8]| section(i, &mut node, &mut dispatch)) + let res = repeat(1.., |i: &mut &'i [u8]| section(i, &mut node, dispatch)) .map(|()| ()) .parse_next(&mut input); res.map_err(|_| { @@ -94,7 +94,7 @@ mod tests; fn section<'i>( i: &mut &'i [u8], node: &mut ParseNode, - dispatch: &mut impl FnMut(Event<'i>), + dispatch: &mut dyn FnMut(Event<'i>), ) -> PResult<(), NomError<&'i [u8]>> { let start = i.checkpoint(); let header = section_header(i).map_err(|e| { @@ -205,7 +205,7 @@ fn is_subsection_unescaped_char(c: u8) -> bool { fn key_value_pair<'i>( i: &mut &'i [u8], node: &mut ParseNode, - dispatch: &mut impl FnMut(Event<'i>), + dispatch: &mut dyn FnMut(Event<'i>), ) -> PResult<(), NomError<&'i [u8]>> { *node = ParseNode::Name; if let Some(name) = opt(config_name).parse_next(i)? { @@ -234,7 +234,7 @@ fn config_name<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> { .parse_next(i) } -fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { +fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { if opt('=').parse_next(i)?.is_some() { dispatch(Event::KeyValueSeparator); if let Some(whitespace) = opt(take_spaces1).parse_next(i)? { @@ -252,7 +252,7 @@ fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> P /// Handles parsing of known-to-be values. This function handles both single /// line values as well as values that are continuations. -fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { +fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> { let start_checkpoint = i.checkpoint(); let mut value_start_checkpoint = i.checkpoint(); let mut value_end = None; diff --git a/gix-config/tests/config.rs b/gix-config/tests/config.rs index 874365a2d06..7107bca8bad 100644 --- a/gix-config/tests/config.rs +++ b/gix-config/tests/config.rs @@ -1,4 +1,4 @@ -type Result = std::result::Result>; +pub use gix_testtools::Result; mod file; mod parse; diff --git a/gix-config/tests/file/init/from_env.rs b/gix-config/tests/file/init/from_env.rs index 4987c60603d..198a25575c9 100644 --- a/gix-config/tests/file/init/from_env.rs +++ b/gix-config/tests/file/init/from_env.rs @@ -44,7 +44,7 @@ fn single_key_value_pair() -> crate::Result { let config = File::from_env(Default::default())?.unwrap(); assert_eq!(config.raw_value("core", None, "key")?, Cow::<[u8]>::Borrowed(b"value")); assert_eq!( - config.section_by_key("core")?.meta(), + config.section_by_key("core".into())?.meta(), &gix_config::file::Metadata::from(gix_config::Source::Env), "source if configured correctly" ); diff --git a/gix-config/tests/file/mod.rs b/gix-config/tests/file/mod.rs index 3a2bc92ab03..2cf50210db7 100644 --- a/gix-config/tests/file/mod.rs +++ b/gix-config/tests/file/mod.rs @@ -21,7 +21,7 @@ mod open { #[test] fn parse_config_with_windows_line_endings_successfully() { - File::from_path_no_includes(&fixture_path_standalone("repo-config.crlf"), gix_config::Source::Local).unwrap(); + File::from_path_no_includes(fixture_path_standalone("repo-config.crlf"), gix_config::Source::Local).unwrap(); } } diff --git a/gix-config/tests/file/mutable/section.rs b/gix-config/tests/file/mutable/section.rs index ea17ce7a401..17ef1df586b 100644 --- a/gix-config/tests/file/mutable/section.rs +++ b/gix-config/tests/file/mutable/section.rs @@ -51,7 +51,7 @@ mod remove { let prev_values = vec!["v", "", "", "", "a b c"]; let mut num_values = section.num_values(); for (key, expected_prev_value) in ('a'..='e').zip(prev_values) { - let prev_value = section.remove(key.to_string()); + let prev_value = section.remove(&key.to_string()); num_values -= 1; assert_eq!(prev_value.expect("present").as_ref(), expected_prev_value); assert_eq!(section.num_values(), num_values); @@ -104,7 +104,7 @@ mod set { for (key, (new_value, expected_prev_value)) in (b'a'..=b'e').zip(values.into_iter().zip(prev_values)) { let key = std::str::from_utf8(std::slice::from_ref(&key))?.to_owned(); - let prev_value = section.set(key.try_into()?, new_value); + let prev_value = section.set(key.try_into()?, new_value.as_ref()); assert_eq!(prev_value.as_deref().expect("prev value set"), expected_prev_value); } @@ -112,7 +112,7 @@ mod set { assert_eq!( config .section_mut("a", None)? - .set("new-one".to_owned().try_into()?, "value"), + .set("new-one".to_owned().try_into()?, "value".into()), None, "new values don't replace an existing one" ); diff --git a/gix-config/tests/file/write.rs b/gix-config/tests/file/write.rs index 3ae71d313ff..26c72c7f72b 100644 --- a/gix-config/tests/file/write.rs +++ b/gix-config/tests/file/write.rs @@ -137,7 +137,7 @@ mod to_filter { .push("c".try_into()?, Some("d".into())); let mut buf = Vec::::new(); - config.write_to_filter(&mut buf, |s| s.meta().source == gix_config::Source::Local)?; + config.write_to_filter(&mut buf, &mut |s| s.meta().source == gix_config::Source::Local)?; let nl = config.detect_newline_style(); assert_eq!(buf.to_str_lossy(), format!("[a \"local\"]{nl}\tb = c{nl}\tc = d{nl}")); diff --git a/gix-config/tests/parse/key.rs b/gix-config/tests/parse/key.rs index 6342429f6e4..40de5ae4269 100644 --- a/gix-config/tests/parse/key.rs +++ b/gix-config/tests/parse/key.rs @@ -2,13 +2,13 @@ use gix_config::parse; #[test] fn missing_dot_is_invalid() { - assert_eq!(parse::key("hello"), None); + assert_eq!(parse::key("hello".into()), None); } #[test] fn section_name_and_key() { assert_eq!( - parse::key("core.bare"), + parse::key("core.bare".into()), Some(parse::Key { section_name: "core", subsection_name: None, @@ -20,7 +20,7 @@ fn section_name_and_key() { #[test] fn section_name_subsection_and_key() { assert_eq!( - parse::key("remote.origin.url"), + parse::key("remote.origin.url".into()), Some(parse::Key { section_name: "remote", subsection_name: Some("origin".into()), @@ -29,7 +29,7 @@ fn section_name_subsection_and_key() { ); assert_eq!( - parse::key("includeIf.gitdir/i:C:\\bare.git.path"), + parse::key("includeIf.gitdir/i:C:\\bare.git.path".into()), Some(parse::Key { section_name: "includeIf", subsection_name: Some("gitdir/i:C:\\bare.git".into()), diff --git a/gix-credentials/src/helper/invoke.rs b/gix-credentials/src/helper/invoke.rs index 563f3b2ffc8..e5662f4ca4e 100644 --- a/gix-credentials/src/helper/invoke.rs +++ b/gix-credentials/src/helper/invoke.rs @@ -4,7 +4,7 @@ use crate::helper::{Action, Context, Error, NextAction, Outcome, Result}; impl Action { /// Send ourselves to the given `write` which is expected to be credentials-helper compatible - pub fn send(&self, mut write: impl std::io::Write) -> std::io::Result<()> { + pub fn send(&self, write: &mut dyn std::io::Write) -> std::io::Result<()> { match self { Action::Get(ctx) => ctx.write_to(write), Action::Store(last) | Action::Erase(last) => { @@ -40,11 +40,12 @@ pub fn invoke(helper: &mut crate::Program, action: &Action) -> Result { } pub(crate) fn raw(helper: &mut crate::Program, action: &Action) -> std::result::Result>, Error> { - let (stdin, stdout) = helper.start(action)?; + let (mut stdin, stdout) = helper.start(action)?; if let (Action::Get(_), None) = (&action, &stdout) { panic!("BUG: `Helper` impls must return an output handle to read output from if Action::Get is provided") } - action.send(stdin)?; + action.send(&mut stdin)?; + drop(stdin); let stdout = stdout .map(|mut stdout| { let mut buf = Vec::new(); diff --git a/gix-credentials/src/program/mod.rs b/gix-credentials/src/program/mod.rs index e13e0a5ecfa..80146601856 100644 --- a/gix-credentials/src/program/mod.rs +++ b/gix-credentials/src/program/mod.rs @@ -39,29 +39,31 @@ impl Program { /// Parse the given input as per the custom helper definition, supporting `!