//! Progress Management Library //! //! This library provides flexible progress management functionality, supporting multi-level progress display and custom renderers. //! //! # Quick Start //! //! The following is a simple usage example demonstrating how to create a progress center, bind a renderer, and update progress for multiple concurrent tasks: //! //! ```rust //! use just_progress::progress; //! use just_progress::renderer::ProgressSimpleRenderer; //! use tokio::time::{sleep, Duration}; //! use tokio::join; //! //! #[tokio::main] //! async fn main() { //! // Initialize the progress center //! let center = progress::init(); //! // Create a renderer and enable subprogress display //! let renderer = ProgressSimpleRenderer::new().with_subprogress(true); //! // Bind the renderer callback function //! let bind = progress::bind(center, move |name, state| renderer.update(name, state)); //! //! // Concurrently execute progress binding and business logic //! join!(bind, proc()); //! } //! //! async fn proc() { //! println!("Starting package download!"); //! sleep(Duration::from_millis(500)).await; //! //! // Define multiple concurrent download tasks //! let download_task = async { //! for i in 1..21 { //! sleep(Duration::from_millis(50)).await; //! progress::update_progress("Download/Data", i as f32 * 0.05); //! } //! }; //! //! let extract_task = async { //! for i in 1..11 { //! sleep(Duration::from_millis(100)).await; //! progress::update_progress("Download/Extract", i as f32 * 0.1); //! } //! }; //! //! let verify_sha256_task = async { //! for i in 1..6 { //! sleep(Duration::from_millis(300)).await; //! progress::update_progress(r"Download\/Verify\/SHA256", i as f32 * 0.2); //! } //! }; //! //! let verify_md5_task = async { //! for i in 1..6 { //! sleep(Duration::from_millis(100)).await; //! progress::update_progress(r"Download\/Verify\/MD5", i as f32 * 0.2); //! } //! }; //! //! let verify_blake3_task = async { //! for i in 1..6 { //! sleep(Duration::from_millis(500)).await; //! progress::update_progress(r"Download\/Verify\/Blake3", i as f32 * 0.2); //! } //! }; //! //! // Concurrently execute all download tasks //! join!( //! download_task, //! extract_task, //! verify_sha256_task, //! verify_blake3_task, //! verify_md5_task //! ); //! //! sleep(Duration::from_millis(500)).await; //! progress::clear_all(); // Clear all progress after download completes //! println!("Package download complete!"); //! //! progress::close(); // Close the progress channel, ending the program //! } //! ``` //! /// Progress Module /// /// Provides core functionality for progress management, including progress center initialization, /// status updates, and callback binding. /// /// # Usage /// /// 1. Initialize the progress center: /// ```rust /// # use just_progress::progress; /// let progress_center = progress::init(); /// ``` /// /// 2. Bind a renderer callback: /// ```rust /// # use just_progress::progress; /// # use just_progress::renderer::ProgressSimpleRenderer; /// let center = progress::init(); /// let renderer = ProgressSimpleRenderer::new().with_subprogress(true); /// let bind = progress::bind(center, move |name, state| renderer.update(name, state)); /// // Run `bind` and business logic in an async context /// ``` /// /// 3. Update progress status: /// ```rust /// # use just_progress::progress::{self, ProgressInfo}; /// // Update progress value /// progress::update_progress(r"download\/file1", 0.5); /// /// // Update status information /// progress::update_info(r"download\/file1", ProgressInfo::Info("Downloading...")); /// /// // Update both progress and status simultaneously /// progress::update(r"download\/file1", 0.75, ProgressInfo::Warning("Slow network")); /// /// // Mark as complete /// // Equivalent to progress::update_progress("download/file1", 1.0); /// progress::complete(r"download\/file1"); /// /// // Clear all progress items /// progress::clear_all(); /// /// // Close the progress channel /// progress::close(); /// ``` /// /// # Special Flags /// /// The module uses two special flags internally to control the flow: /// - `_clear`: Clears all progress items /// - `_close`: Closes the binding channel, stopping callbacks /// /// # Asynchronous Binding /// /// The `bind` function creates an asynchronous Future that listens for progress changes and invokes the callback. /// The callback receives the progress name and state, making it suitable for use with renderers. /// /// # Hierarchical Progress /// /// Progress names can use backslash-slash (`\/`) to represent hierarchical relationships, e.g., `r"parent\/child"`. /// Renderers can leverage this structure to display indentation or calculate the average progress of parent tasks. /// The `\/` separator is used instead of `/` to allow file paths to be used as progress names. /// /// # Notes /// /// - `init()` must be called before using any other functions. /// - When using subprogress, use `\/` as the separator in progress names (e.g., `r"parent\/child"`). /// - The Future returned by `bind()` needs to be polled or awaited for callbacks to execute. /// - `clear_all()` sends a clear signal but does not immediately clear messages in the channel. /// - `close()` stops all `bind()` calls; progress updates are no longer possible afterward. /// pub mod progress; /// Renderer Module /// /// Provides the `ProgressSimpleRenderer` for displaying progress bars and status information. /// /// # Usage /// /// 1. Create a renderer instance: /// ```rust /// # use just_progress::renderer::ProgressSimpleRenderer; /// let renderer = ProgressSimpleRenderer::new(); /// ``` /// /// 2. Configure the renderer (optional): /// ```rust /// # use just_progress::renderer::ProgressSimpleRenderer; /// # use just_progress::renderer::RendererSortingRule; /// let renderer = ProgressSimpleRenderer::new() /// .with_subprogress(true) // Enable subprogress /// .with_auto_remove_completed(true) // Automatically remove completed items /// .with_sorting(RendererSortingRule::AlphabeticalAsc); // Sort alphabetically ascending /// ``` /// /// 3. Trigger rendering: /// ```rust /// # use just_progress::renderer::ProgressSimpleRenderer; /// # use just_progress::renderer::RendererSortingRule; /// # use just_progress::progress::{ProgressState, ProgressInfo}; /// # let renderer = ProgressSimpleRenderer::new(); /// renderer.render_all(); /// ``` /// /// # Subprogress /// /// When `subprogress` is enabled, progress names can be separated by backslash-slash (`\/`) to represent hierarchical relationships: /// - `r"parent"` - Top-level progress /// - `r"parent\/child"` - Subprogress, automatically indented when displayed /// - `r"parent\/child\/grandchild"` - Deeper level progress /// /// If a parent node does not have a directly corresponding progress state, the renderer will automatically calculate the average progress of its child nodes as the display value. /// /// # Theme /// /// Customize the rendering style via the `RendererTheme` struct: /// ```rust /// use just_progress::renderer::{RendererTheme, ProgressSimpleRenderer}; /// let theme = RendererTheme { /// layout: "{name},{progress},{percent}", /// show_state: false, /// progress_content_len: 30, /// progress_filled_char: "█", /// progress_empty_char: "░", /// ..RendererTheme::default() /// }; /// let renderer = ProgressSimpleRenderer::new().with_theme(theme); /// ``` /// /// # Layout /// /// The `layout` field uses a comma-separated template string, supporting the following placeholders: /// - `{name}`: Progress name (supports indentation) /// - `{state}`: Status information (INFO/WARN/ERROR) /// - `{progress}`: Progress bar /// - `{percent}`: Percentage /// /// Example: `"{name},{state},{progress},{percent}"` /// pub mod renderer;