diff --git a/Cargo.toml b/Cargo.toml index 8b77d53..d99d732 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "spinoff" -version = "0.2.0" +version = "0.3.0" edition = "2021" authors = ["ad4m"] description = "🔨 Simple to use Rust library for displaying spinners in the terminal." diff --git a/assets/index.gif b/assets/index.gif index c6e923e..0487069 100644 Binary files a/assets/index.gif and b/assets/index.gif differ diff --git a/examples/stop_and_persist.rs b/examples/stop_and_persist.rs index 827cbd0..766a23a 100644 --- a/examples/stop_and_persist.rs +++ b/examples/stop_and_persist.rs @@ -1,4 +1,4 @@ -use spinoff::{Spinner, Spinners, Color}; +use spinoff::{Color, Spinner, Spinners}; use std::{thread::sleep, time::Duration}; fn main() { diff --git a/src/lib.rs b/src/lib.rs index 5ce2035..df5aa08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,6 +59,8 @@ pub enum Color { Yellow, Cyan, White, + Black, + Magenta, } impl Spinner { @@ -77,7 +79,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", Some(Color::Blue)); + /// let sp = Spinner::new(Spinners::Dots, "Hello World!", Some(Color::Blue)); /// sleep(Duration::from_millis(800)); /// sp.clear(); /// ``` @@ -107,12 +109,12 @@ impl Spinner { .iter() .cycle() .take_while(|_| still_spinning.load(std::sync::atomic::Ordering::Relaxed)); - + // Dynamically delete the last line of the terminal depending on the length of the message + spinner. let mut last_length = 0; for frame in frames { - // This is dependant on the stdout attached is a terminal that respects \r let mut stdout_lock = stdout.lock(); let frame_str = format!(" {} {}", init_color(color, frame.to_string()), msg); + // Get us back to the start of the line. delete_last_line(last_length); last_length = frame_str.bytes().len(); write!(stdout_lock, "{}", frame_str).unwrap(); @@ -144,7 +146,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::Dots9, "Spinning...", None); /// sleep(Duration::from_millis(800)); /// sp.stop(); /// ``` @@ -168,7 +170,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::Dots2, "Hello", None); /// sleep(Duration::from_millis(800)); /// sp.stop_with_message("Bye"); /// ``` @@ -188,7 +190,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::Mindblown, "Guess what's coming...", None); /// sleep(Duration::from_millis(800)); /// sp.stop_and_persist("🍕", "Pizza!"); /// ``` @@ -207,7 +209,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::Aesthetic, "Trying to load information...", None); /// sleep(Duration::from_millis(800)); /// sp.success("Success!"); /// ``` @@ -230,9 +232,9 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::BouncingBar, "Executing code...", None); /// sleep(Duration::from_millis(800)); - /// sp.fail("Failed!"); + /// sp.fail("Code failed to compile!"); /// ``` /// pub fn fail(mut self, msg: StringLiteral) { @@ -249,9 +251,9 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let sp = Spinner::new(Spinners::Material, "Measuring network speed...", None); /// sleep(Duration::from_millis(800)); - /// sp.warn("Look out!"); + /// sp.warn("You might want to check your internet connection..."); /// ``` /// pub fn warn(mut self, msg: StringLiteral) { @@ -275,7 +277,7 @@ impl Spinner { /// let mut sp = Spinner::new(Spinners::Dots, "Hello", None); /// /// sleep(Duration::from_millis(800)); - /// sp.update(Spinners::Dots2, "Goodbye", None); + /// sp.update(Spinners::Dots2, "World", None); /// sleep(Duration::from_millis(800)); /// /// sp.stop(); @@ -298,7 +300,7 @@ impl Spinner { /// # use std::thread::sleep; /// # use std::time::Duration; /// # - /// let mut sp = Spinner::new(Spinners::Dots, "Hello", None); + /// let mut sp = Spinner::new(Spinners::Grenade, "Clearing...", None); /// sleep(Duration::from_millis(800)); /// sp.clear(); /// ``` diff --git a/src/printer.rs b/src/printer.rs index c6faefe..5a7da76 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -22,6 +22,8 @@ pub fn init_color(color: Option, spinner: String) -> Paint { Some(Color::Yellow) => Paint::yellow(spinner), Some(Color::Cyan) => Paint::cyan(spinner), Some(Color::White) => Paint::new(spinner), + Some(Color::Black) => Paint::black(spinner), + Some(Color::Magenta) => Paint::magenta(spinner), None => Paint::new(spinner), } } diff --git a/src/spinner_data.rs b/src/spinner_data.rs index f86a183..a30c9a2 100644 --- a/src/spinner_data.rs +++ b/src/spinner_data.rs @@ -1,4 +1,4 @@ -use crate::{spinner_enum::Spinners, StringLiteral}; +use crate::spinner_enum::Spinners; use maplit::{self, hashmap}; use once_cell::sync::Lazy; use std::collections::HashMap; @@ -7,7 +7,7 @@ use std::collections::HashMap; /// Frames is a Vec of &str, each &str is a frame of the spinner. /// Interval is the number of milliseconds to wait before moving to the next frame. pub struct SpinnerFrames { - pub frames: Vec, + pub frames: Vec<&'static str>, pub interval: u16, } @@ -807,40 +807,40 @@ pub static SPINNER_FRAMES: Lazy> = Lazy::new(|| "(● )" ], interval: 80}, Spinners::Smiley => SpinnerFrames {frames: vec![ - "😄 ", - "😝 " + "😄", + "😝" ], interval: 200}, Spinners::Monkey => SpinnerFrames {frames: vec![ - "🙈 ", - "🙈 ", - "🙉 ", - "🙊 " + "🙈", + "🙈", + "🙉", + "🙊" ], interval: 300}, Spinners::Hearts => SpinnerFrames {frames: vec![ - "💛 ", - "💙 ", - "💜 ", - "💚 ", - "❤️ " + "💛", + "💙", + "💜", + "💚", + "❤️" ], interval: 100}, Spinners::Clock => SpinnerFrames {frames: vec![ - "🕛 ", - "🕐 ", - "🕑 ", - "🕒 ", - "🕓 ", - "🕔 ", - "🕕 ", - "🕖 ", - "🕗 ", - "🕘 ", - "🕙 ", - "🕚 " + "🕛", + "🕐", + "🕑", + "🕒", + "🕓", + "🕔", + "🕕", + "🕖", + "🕗", + "🕘", + "🕙", + "🕚" ], interval: 100}, Spinners::Earth => SpinnerFrames {frames: vec![ - "🌍 ", - "🌎 ", - "🌏 " + "🌍", + "🌎", + "🌏" ], interval: 180}, Spinners::Material => SpinnerFrames {frames: vec![ "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", @@ -937,18 +937,18 @@ pub static SPINNER_FRAMES: Lazy> = Lazy::new(|| "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁" ], interval: 17}, Spinners::Moon => SpinnerFrames {frames: vec![ - "🌑 ", - "🌒 ", - "🌓 ", - "🌔 ", - "🌕 ", - "🌖 ", - "🌗 ", - "🌘 " + "🌑", + "🌒", + "🌓", + "🌔", + "🌕", + "🌖", + "🌗", + "🌘" ], interval: 80}, Spinners::Runner => SpinnerFrames {frames: vec![ - "🚶 ", - "🏃 " + "🚶", + "🏃" ], interval: 140}, Spinners::Pong => SpinnerFrames {frames: vec![ "▐⠂ ▌", @@ -1017,29 +1017,29 @@ pub static SPINNER_FRAMES: Lazy> = Lazy::new(|| "b" ], interval: 100}, Spinners::Weather => SpinnerFrames {frames: vec![ - "☀️ ", - "☀️ ", - "☀️ ", - "🌤 ", - "⛅️ ", - "🌥 ", - "☁️ ", - "🌧 ", - "🌨 ", - "🌧 ", - "🌨 ", - "🌧 ", - "🌨 ", - "⛈ ", - "🌨 ", - "🌧 ", - "🌨 ", - "☁️ ", - "🌥 ", - "⛅️ ", - "🌤 ", - "☀️ ", - "☀️ " + "☀️", + "☀️", + "☀️", + "🌤", + "⛅️", + "🌥", + "☁️", + "🌧", + "🌨", + "🌧", + "🌨", + "🌧", + "🌨", + "⛈", + "🌨", + "🌧", + "🌨", + "☁️", + "🌥", + "⛅️", + "🌤", + "☀️", + "☀️" ], interval: 100}, Spinners::Christmas => SpinnerFrames {frames: vec![ "🌲", @@ -1083,97 +1083,97 @@ pub static SPINNER_FRAMES: Lazy> = Lazy::new(|| "ββββββρ" ], interval: 80}, Spinners::FingerDance => SpinnerFrames {frames: vec![ - "🤘 ", - "🤟 ", - "🖖 ", - "✋ ", - "🤚 ", - "👆 " + "🤘", + "🤟", + "🖖", + "✋", + "🤚", + "👆" ], interval: 160}, Spinners::FistBump => SpinnerFrames {frames: vec![ - "🤜    🤛 ", - "🤜    🤛 ", - "🤜    🤛 ", - " 🤜  🤛  ", - "  🤜🤛   ", - " 🤜✨🤛   ", - "🤜 ✨ 🤛  " + "🤜    🤛", + "🤜    🤛", + "🤜    🤛", + " 🤜  🤛 ", + "  🤜🤛  ", + " 🤜✨🤛  ", + "🤜 ✨ 🤛 " ], interval: 80}, Spinners::SoccerHeader => SpinnerFrames {frames: vec![ - " 🧑⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 ", - "🧑 ⚽️ 🧑 " + " 🧑⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️🧑 ", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑", + "🧑 ⚽️ 🧑" ], interval: 80}, Spinners::Mindblown => SpinnerFrames {frames: vec![ - "😐 ", - "😐 ", - "😮 ", - "😮 ", - "😦 ", - "😦 ", - "😧 ", - "😧 ", - "🤯 ", - "💥 ", - "✨ ", - "  ", - "  ", - "  " + "😐", + "😐", + "😮", + "😮", + "😦", + "😦", + "😧", + "😧", + "🤯", + "💥", + "✨", + " ", + " ", + " " ], interval: 160}, Spinners::Speaker => SpinnerFrames {frames: vec![ - "🔈 ", - "🔉 ", - "🔊 ", - "🔉 " + "🔈", + "🔉", + "🔊", + "🔉" ], interval: 160}, Spinners::OrangePulse => SpinnerFrames {frames: vec![ - "🔸 ", - "🔶 ", - "🟠 ", - "🟠 ", - "🔶 " + "🔸", + "🔶", + "🟠", + "🟠", + "🔶" ], interval: 100}, Spinners::BluePulse => SpinnerFrames {frames: vec![ - "🔹 ", - "🔷 ", - "🔵 ", - "🔵 ", - "🔷 " + "🔹", + "🔷", + "🔵", + "🔵", + "🔷" ], interval: 100}, Spinners::OrangeBluePulse => SpinnerFrames {frames: vec![ - "🔸 ", - "🔶 ", - "🟠 ", - "🟠 ", - "🔶 ", - "🔹 ", - "🔷 ", - "🔵 ", - "🔵 ", - "🔷 " + "🔸", + "🔶", + "🟠", + "🟠", + "🔶", + "🔹", + "🔷", + "🔵", + "🔵", + "🔷" ], interval: 100}, Spinners::TimeTravel => SpinnerFrames {frames: vec![ - "🕛 ", - "🕚 ", - "🕙 ", - "🕘 ", - "🕗 ", - "🕖 ", - "🕕 ", - "🕔 ", - "🕓 ", - "🕒 ", - "🕑 ", - "🕐 " + "🕛", + "🕚", + "🕙", + "🕘", + "🕗", + "🕖", + "🕕", + "🕔", + "🕓", + "🕒", + "🕑", + "🕐" ], interval: 100}, Spinners::Aesthetic => SpinnerFrames {frames: vec![ "▰▱▱▱▱▱▱",