progressed 0.2.1

An easy to use and highly configurable library to show the progress of applications, calculations, ect.
Documentation
use std::io::stdout;

use crossterm::ExecutableCommand;

use crate::{defaults::DEFAULT_WIDTH, style::UnboundProgressBarStyle};

/// Draws a progress bar while iterating over a range.
///
/// # Example Usage
/// ```no_run
///   use progressed::UnboundProgressBar;
///
///   let bar = UnboundProgressBar::new(0..).set_title("Running Job: ");
///   for _ in bar {
///       // prints progress bar
///   }
///
/// ```
pub struct UnboundProgressBar<I: Iterator> {
    data: I,
    current_index: usize,
    title: String,
    style: UnboundProgressBarStyle,
    max_width: usize,
    start_pos: (u16, u16),
}

impl<I: Iterator> UnboundProgressBar<I> {
    pub fn new(iter: I) -> Self {
        let start_pos = crossterm::cursor::position().unwrap_or((0, 0));
        let width = if let Ok((w, _)) = crossterm::terminal::size() {
            (w) as usize
        } else {
            DEFAULT_WIDTH
        };
        Self {
            data: iter,
            current_index: 0,
            title: String::new(),
            style: UnboundProgressBarStyle::default(),
            max_width: width - start_pos.0 as usize,
            start_pos,
        }
    }

    pub fn set_style(mut self, style: UnboundProgressBarStyle) -> Self {
        self.style = style;
        self
    }
    pub fn set_title(mut self, title: &str) -> Self {
        self.title = title.to_owned();
        self
    }

    pub fn set_max_width(mut self, max_width: usize) -> Self {
        self.max_width = max_width;
        self
    }
}

impl<I: Iterator> Iterator for UnboundProgressBar<I> {
    type Item = I::Item;
    fn next(&mut self) -> Option<Self::Item> {
        let str_len = self.current_index;

        let title = &self.title;
        let max_width = self.max_width - self.title.len();
        let width = str_len % max_width;

        let tip = self.style.get_tip_symbol();
        let fg_symbol = self.style.get_fg_symbol();
        let fg = vec![fg_symbol.to_string(); width].join("");
        let bg = vec![" "; max_width - width - 1].join("");

        if stdout().execute(crossterm::cursor::Hide).is_ok() {}

        let (x, y) = self.start_pos;
        if let Ok(_) = stdout().execute(crossterm::cursor::MoveTo(x, y)) {}

        print!("{title}{fg}{tip}{bg}");

        self.current_index += 1;
        self.data.next()
    }
}