Skip to content
Snippets Groups Projects
Commit b2f9b846 authored by Michael Hauspie's avatar Michael Hauspie
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "progress"
version = "0.1.0"
[package]
name = "progress"
version = "0.1.0"
edition = "2024"
[dependencies]
//! This crates demonstrates the use of extension traits and Type State encoding.
//!
//! The original idea is borrowed from Will Crichton's talk at Strangeloop 2021
//!
//! https://www.youtube.com/watch?v=bnnacleqg6k
//!
const CLEAR: &str = "\x1b[2J\x1b[1;1H";
fn compute<T>(_val: T) {
std::thread::sleep(std::time::Duration::from_millis(600));
}
/// This type defines the /unbounded/ state for our progress bar
struct Unbounded;
/// This type defines the /bounded/ state for our progress bar
struct Bounded {
bound: usize,
}
/// Defines how to display a progress bar
trait ProgressDisplay: Sized {
/// Displays the progress bar. It is for each item yielded by the iterator
fn display<Iter>(&self, progress: &Progress<Iter, Self>);
}
impl ProgressDisplay for Unbounded {
fn display<Iter>(&self, progress: &Progress<Iter, Self>) {
println!("{}{}", CLEAR, "*".repeat(progress.i));
}
}
impl ProgressDisplay for Bounded {
fn display<Iter>(&self, progress: &Progress<Iter, Self>) {
println!(
"{}[{}{}]",
CLEAR,
"*".repeat(progress.i),
"-".repeat(self.bound - progress.i)
);
}
}
#[derive(Debug)]
/// An Iterator that display progress
struct Progress<Iter, Bound> {
iter: Iter,
i: usize,
bound: Bound,
}
impl<Iter: ExactSizeIterator> Progress<Iter, Unbounded> {
/// Creates a new bounded progress bar from an unbounded one
fn with_bounds(self) -> Progress<Iter, Bounded> {
let bound = Bounded {
bound: self.iter.len(),
};
Progress {
iter: self.iter,
i: self.i,
bound,
}
}
}
impl<Iter: Iterator, Bound: ProgressDisplay> Iterator for Progress<Iter, Bound> {
type Item = Iter::Item;
fn next(&mut self) -> Option<Self::Item> {
self.bound.display(self);
self.i += 1;
self.iter.next()
}
}
/// A trait that allows the creation of a progress bar from a type
trait ProgressIteratorExt: Sized {
/// Create a new unbounded progress bar from self
fn progress(self) -> Progress<Self, Unbounded>;
}
impl<Iter: Iterator> ProgressIteratorExt for Iter {
fn progress(self) -> Progress<Self, Unbounded> {
Progress {
iter: self,
i: 0,
bound: Unbounded,
}
}
}
fn main() {
let values = [1, 2, 3];
for v in values.iter().progress().with_bounds() {
compute(v);
}
for v in (0..).progress() {
compute(v);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment