Skip to main content

LoomRuntime

Struct LoomRuntime 

Source
pub struct LoomRuntime { /* private fields */ }
Expand description

A bespoke thread pool runtime combining tokio and rayon with CPU pinning.

The runtime provides:

  • A tokio async runtime for I/O-bound work
  • A rayon thread pool for CPU-bound parallel work
  • Automatic CPU pinning for both runtimes
  • A task tracker for graceful shutdown
  • Zero-allocation compute spawning after warmup

§Performance Guarantees

MethodOverheadAllocationsTracked
spawn_async()~10nsToken onlyYes
spawn_compute()~100-500ns0 bytes (after warmup)Yes
install()~0nsNoneNo
rayon_pool()0nsNoneNo
tokio_handle()0nsNoneNo

§Examples

use loom_rs::LoomBuilder;

let runtime = LoomBuilder::new()
    .prefix("myapp")
    .tokio_threads(2)
    .rayon_threads(6)
    .build()?;

runtime.block_on(async {
    // Spawn tracked async I/O task
    let io_handle = runtime.spawn_async(async {
        fetch_data().await
    });

    // Spawn tracked compute task and await result
    let result = runtime.spawn_compute(|| {
        expensive_computation()
    }).await;

    // Zero-overhead parallel iterators (within tracked context)
    let processed = runtime.install(|| {
        data.par_iter().map(|x| process(x)).collect()
    });
});

// Graceful shutdown from main thread
runtime.block_until_idle();

Implementations§

Source§

impl LoomRuntime

Source

pub fn config(&self) -> &LoomConfig

Get the resolved configuration.

Source

pub fn tokio_handle(&self) -> &Handle

Get the tokio runtime handle.

This can be used to spawn untracked tasks or enter the runtime context. For tracked async tasks, prefer spawn_async().

§Performance

Zero overhead - returns a reference.

Source

pub fn rayon_pool(&self) -> &ThreadPool

Get the rayon thread pool.

This can be used to execute parallel iterators or spawn untracked work directly. For tracked compute tasks, prefer spawn_compute(). For zero-overhead parallel iterators, prefer install().

§Performance

Zero overhead - returns a reference.

Source

pub fn task_tracker(&self) -> &TaskTracker

Get the task tracker for graceful shutdown.

Use this to track spawned tasks and wait for them to complete.

Source

pub fn block_on<F: Future>(&self, f: F) -> F::Output

Block on a future using the tokio runtime.

This is the main entry point for running async code from the main thread. The current runtime is available via loom_rs::current_runtime() within the block_on scope.

§Examples
runtime.block_on(async {
    // Async code here
    // loom_rs::current_runtime() works here
});
Source

pub fn spawn_async<F>(&self, future: F) -> JoinHandle<F::Output>
where F: Future + Send + 'static, F::Output: Send + 'static,

Spawn a tracked async task on tokio.

The task is tracked for graceful shutdown via block_until_idle().

§Performance

Overhead: ~10ns (TaskTracker token only).

§Examples
runtime.block_on(async {
    let handle = runtime.spawn_async(async {
        // I/O-bound async work
        fetch_data().await
    });

    let result = handle.await.unwrap();
});
Source

pub async fn spawn_compute<F, R>(&self, f: F) -> R
where F: FnOnce() -> R + Send + 'static, R: Send + 'static,

Spawn CPU-bound work on rayon and await the result.

The task is tracked for graceful shutdown via block_until_idle(). Automatically uses per-type object pools for zero allocation after warmup.

§Performance
StateAllocationsOverhead
Pool hit0 bytes~100-500ns
Pool miss~32 bytes~100-500ns
First call per typePool + state~1µs

For zero-overhead parallel iterators (within an already-tracked context), use install() instead.

§Examples
runtime.block_on(async {
    let result = runtime.spawn_compute(|| {
        // CPU-intensive work
        expensive_computation()
    }).await;
});
Source

pub async fn spawn_adaptive<F, R>(&self, f: F) -> R
where F: FnOnce() -> R + Send + 'static, R: Send + 'static,

Spawn work with adaptive inline/offload decision.

Uses MAB (Multi-Armed Bandit) to learn whether this function type should run inline on tokio or offload to rayon. Good for handler patterns where work duration varies by input.

Unlike spawn_compute() which always offloads, this adaptively chooses based on learned behavior and current system pressure.

§Performance
ScenarioBehaviorOverhead
Fast workInlines after learning~100ns (decision only)
Slow workOffloads after learning~100-500ns (+ offload)
Cold startExplores both armsVariable
§Examples
runtime.block_on(async {
    // MAB will learn whether this is fast or slow
    let result = runtime.spawn_adaptive(|| {
        process_item(item)
    }).await;
});
Source

pub async fn spawn_adaptive_with_hint<F, R>(&self, hint: ComputeHint, f: F) -> R
where F: FnOnce() -> R + Send + 'static, R: Send + 'static,

Spawn with hint for cold-start guidance.

The hint helps the scheduler make better initial decisions before it has learned the actual execution time of this function type.

§Hints
  • ComputeHint::Low - Expected < 50µs (likely inline-safe)
  • ComputeHint::Medium - Expected 50-500µs (borderline)
  • ComputeHint::High - Expected > 500µs (should test offload early)
  • ComputeHint::Unknown - No hint (default exploration)
§Examples
use loom_rs::ComputeHint;

runtime.block_on(async {
    // Hint that this is likely slow work
    let result = runtime.spawn_adaptive_with_hint(
        ComputeHint::High,
        || expensive_computation()
    ).await;
});
Source

pub fn install<F, R>(&self, f: F) -> R
where F: FnOnce() -> R + Send, R: Send,

Execute work on rayon with zero overhead (sync, blocking).

This installs the rayon pool for the current scope, allowing direct use of rayon’s parallel iterators.

NOT tracked - use within an already-tracked task (e.g., inside spawn_async or spawn_compute) for proper shutdown tracking.

§Performance

Zero overhead - direct rayon access.

§Examples
runtime.block_on(async {
    // This is a tracked context (we're in block_on)
    let processed = runtime.install(|| {
        use rayon::prelude::*;
        data.par_iter().map(|x| process(x)).collect::<Vec<_>>()
    });
});
Source

pub async fn scope_compute<'env, F, R>(&self, f: F) -> R
where F: FnOnce(&Scope<'env>) -> R + Send + 'env, R: Send + 'env,

Execute a scoped parallel computation, allowing borrowed data.

Unlike spawn_compute() which requires 'static bounds, scope_compute allows borrowing local variables from the async context for use in parallel work. This is safe because:

  1. The .await suspends the async task
  2. rayon::scope blocks until ALL spawned work completes
  3. Only then does the future resolve
  4. Therefore, borrowed references remain valid throughout
§Performance
AspectValue
Allocation~96 bytes per call (not pooled)
OverheadComparable to spawn_compute()

State cannot be pooled because the result type R may contain borrowed references tied to the calling scope. Benchmarks show performance is within noise of spawn_compute() - the overhead is dominated by cross-thread communication, not state management.

§Cancellation Safety

If the future is dropped before completion (e.g., via select! or timeout), the drop will block until the rayon scope finishes. This is necessary to prevent use-after-free of borrowed data. In normal usage (awaiting to completion), there is no blocking overhead.

§Panic Safety

If the closure or any spawned work panics, the panic is captured and re-raised when the future is polled. This ensures panics propagate to the async context as expected.

§Leaking the Future

Important: Do not leak this future via std::mem::forget or similar. The safety of borrowed data relies on the future’s Drop implementation blocking until the rayon scope completes. Leaking the future would allow the rayon work to continue accessing borrowed data after it goes out of scope, leading to undefined behavior. This is a known limitation shared by other scoped async APIs (e.g., async-scoped).

§Examples
use std::sync::atomic::{AtomicI32, Ordering};

runtime.block_on(async {
    let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
    let sum = AtomicI32::new(0);

    // Borrow `data` and `sum` for parallel processing
    runtime.scope_compute(|s| {
        let (left, right) = data.split_at(data.len() / 2);

        s.spawn(|_| {
            sum.fetch_add(left.iter().sum(), Ordering::Relaxed);
        });
        s.spawn(|_| {
            sum.fetch_add(right.iter().sum(), Ordering::Relaxed);
        });
    }).await;

    // `data` and `sum` are still valid here
    println!("Sum of {:?} = {}", data, sum.load(Ordering::Relaxed));
});
Source

pub async fn scope_adaptive<'env, F, R>(&self, f: F) -> R
where F: FnOnce(&Scope<'env>) -> R + Send + 'env, R: Send + 'env,

Execute scoped work with adaptive sync/async decision.

Uses MAB (Multi-Armed Bandit) to learn whether this function type should:

  • Run synchronously via install() (blocks tokio worker, lower overhead)
  • Run asynchronously via scope_compute() (frees tokio worker, higher overhead)

Unlike spawn_adaptive() which chooses between inline execution and rayon offload, scope_adaptive always uses rayon::scope (needed for parallel spawning with borrowed data), but chooses whether to block the tokio worker or use the async bridge.

§Performance
ScenarioBehaviorOverhead
Fast scoped workSync after learning~0ns (install overhead only)
Slow scoped workAsync after learning~100-500ns (+ bridge)
Cold startExplores both armsVariable
§When to Use

Use scope_adaptive when:

  • You need to borrow local data ('env lifetime)
  • You want parallel spawning via rayon::scope
  • Work duration varies and you want the runtime to learn the best strategy

Use scope_compute directly when:

  • Work is always slow (> 500µs)
  • You want consistent async behavior
§Examples
use std::sync::atomic::{AtomicI32, Ordering};

runtime.block_on(async {
    let data = vec![1, 2, 3, 4, 5, 6, 7, 8];
    let sum = AtomicI32::new(0);

    // MAB learns whether this is fast or slow scoped work
    runtime.scope_adaptive(|s| {
        let (left, right) = data.split_at(data.len() / 2);
        let sum_ref = &sum;

        s.spawn(move |_| {
            sum_ref.fetch_add(left.iter().sum(), Ordering::Relaxed);
        });
        s.spawn(move |_| {
            sum_ref.fetch_add(right.iter().sum(), Ordering::Relaxed);
        });
    }).await;

    println!("Sum: {}", sum.load(Ordering::Relaxed));
});
Source

pub async fn scope_adaptive_with_hint<'env, F, R>( &self, hint: ComputeHint, f: F, ) -> R
where F: FnOnce(&Scope<'env>) -> R + Send + 'env, R: Send + 'env,

Execute scoped work with hint for cold-start guidance.

The hint helps the scheduler make better initial decisions before it has learned the actual execution time of this function type.

§Hints
  • ComputeHint::Low - Expected < 50µs (likely sync-safe)
  • ComputeHint::Medium - Expected 50-500µs (borderline)
  • ComputeHint::High - Expected > 500µs (should test async early)
  • ComputeHint::Unknown - No hint (default exploration)
§Examples
use loom_rs::ComputeHint;
use std::sync::atomic::{AtomicI32, Ordering};

runtime.block_on(async {
    let data = vec![1, 2, 3, 4];
    let sum = AtomicI32::new(0);

    // Hint that this is likely fast work
    runtime.scope_adaptive_with_hint(ComputeHint::Low, |s| {
        let sum_ref = &sum;
        for &val in &data {
            s.spawn(move |_| {
                sum_ref.fetch_add(val, Ordering::Relaxed);
            });
        }
    }).await;
});
Source

pub fn shutdown(&self)

Stop accepting new tasks.

After calling this, spawn_async() and spawn_compute() will still work, but the shutdown process has begun. Use is_idle() or wait_for_shutdown() to check/wait for completion.

Source

pub fn is_idle(&self) -> bool

Check if all tracked tasks have completed.

Returns true if shutdown() has been called and all tracked async tasks and compute tasks have finished.

§Performance

Zero overhead - single atomic load.

Source

pub fn compute_tasks_in_flight(&self) -> usize

Get the number of compute tasks currently in flight.

Useful for debugging shutdown issues or monitoring workload.

§Example
if runtime.compute_tasks_in_flight() > 0 {
    tracing::warn!("Still waiting for {} compute tasks",
        runtime.compute_tasks_in_flight());
}
Source

pub async fn wait_for_shutdown(&self)

Wait for all tracked tasks to complete (async).

Call from within block_on(). Requires shutdown() to be called first, otherwise this will wait forever.

§Examples
runtime.block_on(async {
    runtime.spawn_async(work());
    runtime.shutdown();
    runtime.wait_for_shutdown().await;
});
Source

pub fn block_until_idle(&self)

Block until all tracked tasks complete (from main thread).

This is the primary shutdown method. It:

  1. Calls shutdown() to close the task tracker
  2. Waits for all tracked async and compute tasks to finish
§Examples
runtime.block_on(async {
    runtime.spawn_async(background_work());
    runtime.spawn_compute(|| cpu_work());
});

// Graceful shutdown from main thread
runtime.block_until_idle();
Source

pub fn mab_scheduler(&self) -> Arc<MabScheduler>

Get the shared MAB scheduler for handler patterns.

The scheduler is lazily initialized on first call. Use this when you need to make manual scheduling decisions in handler code.

§Example
use loom_rs::mab::{FunctionKey, Arm};

let sched = runtime.mab_scheduler();
let key = FunctionKey::from_type::<MyHandler>();
let ctx = runtime.collect_context();

let (id, arm) = sched.choose(key, &ctx);
let result = match arm {
    Arm::InlineTokio => my_work(),
    Arm::OffloadRayon => runtime.block_on(async {
        runtime.spawn_compute(|| my_work()).await
    }),
};
sched.finish(id, elapsed_us, Some(fn_us));
Source

pub fn collect_context(&self) -> Context

Collect current runtime context for MAB scheduling decisions.

Returns a snapshot of current metrics including inflight tasks, spawn rate, and queue depth.

Source

pub fn tokio_threads(&self) -> usize

Get the number of tokio worker threads.

Source

pub fn rayon_threads(&self) -> usize

Get the number of rayon threads.

Source

pub fn prometheus_metrics(&self) -> &LoomMetrics

Get the Prometheus metrics.

The metrics are always collected (zero overhead atomic operations). If a Prometheus registry was provided via LoomBuilder::prometheus_registry(), the metrics are also registered for exposition.

Source

pub fn tokio_cpus(&self) -> &[usize]

Get the CPUs allocated to tokio workers.

Source

pub fn rayon_cpus(&self) -> &[usize]

Get the CPUs allocated to rayon workers.

Trait Implementations§

Source§

impl Debug for LoomRuntime

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for LoomRuntime

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Paint for T
where T: ?Sized,

Source§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
Source§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
Source§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
Source§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
Source§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling Attribute value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
Source§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
Source§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi Quirk value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
Source§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
Source§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
Source§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the Condition value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more