//! Shared progress core for the standalone (non-[`Group`](crate::future::Group)) rendering path. //! //! Every standalone adapter ([`ProgressFuture`](crate::future::ProgressFuture), //! [`Join`](crate::future::Join) and the three stream wrappers) carries the same machinery: the //! dynamic [`State`], the per-row theme / style overrides, and the lazily materialised rendering //! bits (line, spinner ticks, cursor guard). [`Progress`] bundles all of that and owns the render //! loop, so an adapter only has to spell out how one of its items maps onto progress and forward //! the [`Progressive`] methods to its `core`. use std::borrow::Cow; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration; use futures_lite::Stream as _; use owo_colors::Style; use crate::line::{FrameContext, Line}; use crate::progressive::Progressive; use crate::spinner::Ticks; use crate::state::State; use crate::term::{CursorGuard, Output}; use crate::Theme; /// Materialised rendering bits used by the standalone path: line, spinner ticks, cursor guard. struct Rendering<'a> { line: Line<'a>, ticks: Ticks<'a>, spinner_frame: Option<&'a str>, spinner_tick: u64, spinner_style: Style, annotation_style: Style, output: Output, is_tty: bool, _guard: CursorGuard, } /// Lifecycle of the standalone rendering bits. enum RenderingState<'a> { /// Constructed but not yet polled; materialised on the first poll. Pending, /// Materialised; standalone rendering is active. Active(Rendering<'a>), /// A [`Group`](crate::future::Group) owns rendering for this row; nothing is rendered here. Detached, } /// Per-row dynamic [`State`], theme / style overrides and the standalone rendering machinery, /// shared by every progress adapter. pub(crate) struct Progress<'a> { pub(crate) state: State, theme_override: Option>, spinner_style_override: Option