summaryrefslogtreecommitdiffstats
path: root/vendor/gix-features/src/progress.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-features/src/progress.rs')
-rw-r--r--vendor/gix-features/src/progress.rs139
1 files changed, 139 insertions, 0 deletions
diff --git a/vendor/gix-features/src/progress.rs b/vendor/gix-features/src/progress.rs
new file mode 100644
index 000000000..b6e56895b
--- /dev/null
+++ b/vendor/gix-features/src/progress.rs
@@ -0,0 +1,139 @@
+//! Various `prodash` types along with various utilities for comfort.
+use std::io;
+
+pub use prodash::{
+ self,
+ messages::MessageLevel,
+ progress::{Discard, DoOrDiscard, Either, Id, Step, StepShared, Task, ThroughputOnDrop, Value, UNKNOWN},
+ unit, Progress, Unit,
+};
+
+#[cfg(feature = "progress-unit-bytes")]
+pub use bytesize;
+/// A stub for the portions of the `bytesize` crate that we use internally in `gitoxide`.
+#[cfg(not(feature = "progress-unit-bytes"))]
+pub mod bytesize {
+ /// A stub for the `ByteSize` wrapper.
+ pub struct ByteSize(pub u64);
+
+ impl std::fmt::Display for ByteSize {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.fmt(f)
+ }
+ }
+}
+
+/// A unit for displaying bytes with throughput and progress percentage.
+#[cfg(feature = "progress-unit-bytes")]
+pub fn bytes() -> Option<Unit> {
+ Some(unit::dynamic_and_mode(
+ unit::Bytes,
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying bytes with throughput and progress percentage.
+#[cfg(not(feature = "progress-unit-bytes"))]
+pub fn bytes() -> Option<Unit> {
+ Some(unit::label_and_mode(
+ "B",
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying human readable numbers with throughput and progress percentage, and a single decimal place.
+pub fn count(name: &'static str) -> Option<Unit> {
+ count_with_decimals(name, 1)
+}
+
+/// A unit for displaying human readable numbers with `name` suffix,
+/// with throughput and progress percentage, and `decimals` decimal places.
+#[cfg(feature = "progress-unit-human-numbers")]
+pub fn count_with_decimals(name: &'static str, decimals: usize) -> Option<Unit> {
+ Some(unit::dynamic_and_mode(
+ unit::Human::new(
+ {
+ let mut f = unit::human::Formatter::new();
+ f.with_decimals(decimals);
+ f
+ },
+ name,
+ ),
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A unit for displaying human readable numbers with `name` suffix,
+/// with throughput and progress percentage, and `decimals` decimal places.
+#[cfg(not(feature = "progress-unit-human-numbers"))]
+pub fn count_with_decimals(name: &'static str, _decimals: usize) -> Option<Unit> {
+ Some(unit::label_and_mode(
+ name,
+ unit::display::Mode::with_throughput().and_percentage(),
+ ))
+}
+
+/// A predefined unit for displaying a multi-step progress
+pub fn steps() -> Option<Unit> {
+ 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()].
+pub struct Read<T, P> {
+ /// The implementor of [`std::io::Read`] to which progress is added
+ pub inner: T,
+ /// The progress instance receiving progress information on each invocation of `reader`
+ pub progress: P,
+}
+
+impl<T, P> io::Read for Read<T, P>
+where
+ T: io::Read,
+ P: Progress,
+{
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ let bytes_read = self.inner.read(buf)?;
+ self.progress.inc_by(bytes_read);
+ Ok(bytes_read)
+ }
+}
+
+impl<T, P> io::BufRead for Read<T, P>
+where
+ T: io::BufRead,
+ P: Progress,
+{
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ self.inner.fill_buf()
+ }
+
+ fn consume(&mut self, amt: usize) {
+ self.inner.consume(amt)
+ }
+}
+
+/// A structure passing every [`write`][std::io::Write::write()] call through to the contained Progress instance using [`inc_by(bytes_written)`][Progress::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<T, P> {
+ /// The implementor of [`std::io::Write`] to which progress is added
+ pub inner: T,
+ /// The progress instance receiving progress information on each invocation of `reader`
+ pub progress: P,
+}
+
+impl<T, P> io::Write for Write<T, P>
+where
+ T: io::Write,
+ P: Progress,
+{
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ let written = self.inner.write(buf)?;
+ self.progress.inc_by(written);
+ Ok(written)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.inner.flush()
+ }
+}