### Ratatui Integration Source: https://context7.com/aschey/termprofile/llms.txt Enables direct use of `ratatui::style::Color` and `ratatui::style::Style` with `adapt_color` and `adapt_style`. It's crucial to detect the terminal profile before initializing Ratatui. ```APIDOC ## Ratatui Integration (`ratatui` + `convert` features) With the `ratatui` feature, `adapt_color` and `adapt_style` accept and return native `ratatui::style::Color` and `ratatui::style::Style` types directly — including the `Color::Reset` variant that `anstyle` does not support. Detect the profile **before** calling `ratatui::init()` because DECRQSS querying modifies terminal state. ```rust // Cargo.toml: termprofile = { features = ["ratatui", "convert", "query-detect"] } use std::io::{self, stdout}; use ratatui::style::{Color, Style}; use termprofile::{DetectorSettings, TermProfile}; fn main() -> io::Result<()> { // Detect BEFORE ratatui::init() takes over the terminal let profile = TermProfile::detect(&stdout(), DetectorSettings::with_query()?); let terminal = ratatui::init(); let result = run(terminal, profile); ratatui::restore(); result } fn render_frame(profile: &TermProfile) -> Style { // Use RGB colors in your app logic; termprofile downgrades automatically let rgb_fg = Color::Rgb(106, 132, 92); let rgb_bg = Color::Rgb(4, 35, 212); let style = Style::new().fg(rgb_fg).bg(rgb_bg); // Returns a Style with colors appropriate for the actual terminal profile.adapt_style(style) // On TrueColor: Style { fg: Rgb(106,132,92), bg: Rgb(4,35,212) } // On Ansi16: Style { fg: Cyan, bg: BrightBlue } // On NoTty: Style::default() } # fn run(_: ratatui::DefaultTerminal, _: TermProfile) -> io::Result<()> { Ok(()) } ``` ``` -------------------------------- ### Ratatui Integration for Adaptive Styling Source: https://context7.com/aschey/termprofile/llms.txt Integrate termprofile with Ratatui to automatically adapt styles to the terminal's capabilities. Detect the profile before initializing Ratatui. Requires `ratatui`, `convert`, and `query-detect` features. ```rust // Cargo.toml: termprofile = { features = ["ratatui", "convert", "query-detect"] } use std::io::{self, stdout}; use ratatui::style::{Color, Style}; use termprofile::{DetectorSettings, TermProfile}; fn main() -> io::Result<()> { // Detect BEFORE ratatui::init() takes over the terminal let profile = TermProfile::detect(&stdout(), DetectorSettings::with_query()?); let terminal = ratatui::init(); let result = run(terminal, profile); ratatui::restore(); result } fn render_frame(profile: &TermProfile) -> Style { // Use RGB colors in your app logic; termprofile downgrades automatically let rgb_fg = Color::Rgb(106, 132, 92); let rgb_bg = Color::Rgb(4, 35, 212); let style = Style::new().fg(rgb_fg).bg(rgb_bg); // Returns a Style with colors appropriate for the actual terminal profile.adapt_style(style) // On TrueColor: Style { fg: Rgb(106,132,92), bg: Rgb(4,35,212) } // On Ansi16: Style { fg: Cyan, bg: BrightBlue } // On NoTty: Style::default() } # fn run(_: ratatui::DefaultTerminal, _: TermProfile) -> io::Result<()> { Ok(()) } ``` -------------------------------- ### Configuring DetectorSettings Source: https://context7.com/aschey/termprofile/llms.txt Customizes the behavior of `TermProfile::detect` by enabling or disabling specific detection mechanisms. Settings default to on, except for the DECRQSS query which requires a feature flag and involves I/O. ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Default: terminfo + tmux info enabled, query disabled let settings = DetectorSettings::default(); let profile = TermProfile::detect(&stdout(), settings); ``` ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Disable tmux info subprocess call (useful in constrained environments) let settings = DetectorSettings::new() .enable_tmux_info(false); let profile = TermProfile::detect(&stdout(), settings); ``` ```rust use std::time::Duration; use termprofile::{TermProfile, DetectorSettings}; use termprofile::DefaultTerminal; // Enable DECRQSS terminal query (requires `query-detect` feature) // Uses a 100ms timeout by default let terminal = DefaultTerminal::new() .unwrap() .timeout(Duration::from_millis(200)); // custom timeout let settings = DetectorSettings::new().query_terminal(terminal); let profile = TermProfile::detect(&stdout(), settings); println!("Profile (custom query timeout): {profile:?}"); ``` -------------------------------- ### Adapt Style with TermProfile (Ansi16) Source: https://github.com/aschey/termprofile/blob/main/README.md Demonstrates adapting an anstyle Style to the Ansi16 profile. Ensure anstyle is imported for this functionality. ```rust use termprofile::TermProfile; use std::io::stdout; use anstyle::{Color, RgbColor, AnsiColor, Style}; let profile = TermProfile::Ansi16; let fg = RgbColor(106, 132, 92).into(); let bg = RgbColor(4, 35, 212).into(); let style = Style::new().fg_color(Some(fg)).bg_color(Some(bg)); let adapted_style = profile.adapt_style(style); assert_eq!( adapted_style, Style::new() .fg_color(Some(AnsiColor::Cyan.into())) .bg_color(Some(AnsiColor::BrightBlue.into())) ); ``` -------------------------------- ### Full Style Downconversion with `adapt_style` Source: https://context7.com/aschey/termprofile/llms.txt Adapts an entire `anstyle::Style` (foreground, background, and underline color) for the current terminal profile. On `NoTty`, returns a default (empty) style. Requires the `convert` feature. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, AnsiColor, Style}; let fg: Color = RgbColor(106, 132, 92).into(); let bg: Color = RgbColor(4, 35, 212).into(); let style = Style::new().fg_color(Some(fg)).bg_color(Some(bg)); // Ansi16 profile: both fg and bg are mapped to nearest named colors let profile = TermProfile::Ansi16; let adapted = profile.adapt_style(style); assert_eq!( adapted, Style::new() .fg_color(Some(AnsiColor::Cyan.into())) .bg_color(Some(AnsiColor::BrightBlue.into())) ); ``` ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, AnsiColor, Style}; let fg: Color = RgbColor(106, 132, 92).into(); let bg: Color = RgbColor(4, 35, 212).into(); let style = Style::new().fg_color(Some(fg)).bg_color(Some(bg)); // NoTty profile: all styling stripped entirely let no_tty = TermProfile::NoTty; assert_eq!(no_tty.adapt_style(style), Style::default()); ``` -------------------------------- ### Color Index Conversion Utilities Source: https://context7.com/aschey/termprofile/llms.txt Provides standalone functions for converting ANSI 256 color indices to their nearest ANSI 16 color equivalent or their canonical RGB values, without requiring a full terminal profile. ```APIDOC ## `ansi256_to_ansi16` and `ansi256_to_rgb` — Color Index Conversion Utilities (`convert` feature) Standalone free functions for one-off color index conversions without going through a profile. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::{ansi256_to_ansi16, ansi256_to_rgb}; use anstyle::{Ansi256Color, AnsiColor}; // Convert an ANSI 256 index to the nearest of the 16 named colors let ansi16 = ansi256_to_ansi16(32); // index 32 is a blue-green println!("{ansi16:?}"); // e.g. AnsiColor::Cyan // Convert an ANSI 256 index to its canonical RGB value let rgb = ansi256_to_rgb(Ansi256Color(196)); // index 196 is pure red assert_eq!(rgb, anstyle::RgbColor(255, 0, 0)); ``` ``` -------------------------------- ### Color Index Conversion Utilities Source: https://context7.com/aschey/termprofile/llms.txt Standalone functions `ansi256_to_ansi16` and `ansi256_to_rgb` allow for direct color index conversions without involving a profile. Ensure the `convert` feature is enabled. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::{ansi256_to_ansi16, ansi256_to_rgb}; use anstyle::{Ansi256Color, AnsiColor}; // Convert an ANSI 256 index to the nearest of the 16 named colors let ansi16 = ansi256_to_ansi16(32); // index 32 is a blue-green println!("{ansi16:?}"); // e.g. AnsiColor::Cyan // Convert an ANSI 256 index to its canonical RGB value let rgb = ansi256_to_rgb(Ansi256Color(196)); // index 196 is pure red assert_eq!(rgb, anstyle::RgbColor(255, 0, 0)); ``` -------------------------------- ### Controlled Color Adaptation with ProfileColor Source: https://github.com/aschey/termprofile/blob/main/README.md Provides fine-grained control over color adaptation by specifying fallback colors for different terminal capabilities (ANSI 256, ANSI 16). Creates a ProfileColor and adapts it. ```rust use termprofile::{TermProfile, ProfileColor}; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; let profile = TermProfile::Ansi256; let color = ProfileColor::new(Color::Rgb(RgbColor(209, 234, 213)), profile) .ansi_256(240) .ansi_16(AnsiColor::White); assert_eq!(color.adapt(), Some(Ansi256Color(240).into())); ``` -------------------------------- ### Adapt Color with TermProfile (Ansi256) for Ratatui Source: https://github.com/aschey/termprofile/blob/main/README.md Shows how to adapt a ratatui Color to the Ansi256 profile when the 'ratatui' feature is enabled. This ensures compatibility without anstyle as an intermediate. ```rust use termprofile::TermProfile; use std::io::stdout; use ratatui::style::Color; let profile = TermProfile::Ansi256; let rgb_color = Color::Rgb(209, 234, 213); let adapted_color = profile.adapt_color(rgb_color); assert_eq!(adapted_color, Some(Color::Indexed(253))); ``` -------------------------------- ### Enable and Configure Color Cache Source: https://github.com/aschey/termprofile/blob/main/README.md Enables the color caching feature and sets the cache size. This is an opt-in feature for performance optimization. ```rust use termprofile::{set_color_cache_enabled, set_color_cache_size}; set_color_cache_enabled(true); set_color_cache_size(256.try_into().expect("non-zero size")); ``` -------------------------------- ### DetectorSettings Source: https://context7.com/aschey/termprofile/llms.txt A builder-style struct that controls which detection mechanisms are enabled for TermProfile::detect. All settings default to on except the DECRQSS terminal query. ```APIDOC ## `DetectorSettings` — Detection Configuration Builder-style struct that controls which detection mechanisms are enabled. All settings default to on except the DECRQSS terminal query (which requires the `query-detect` feature and involves I/O). ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Default: terminfo + tmux info enabled, query disabled let settings = DetectorSettings::default(); let profile = TermProfile::detect(&stdout(), settings); // Disable tmux info subprocess call (useful in constrained environments) let settings = DetectorSettings::new() .enable_tmux_info(false); let profile = TermProfile::detect(&stdout(), settings); // Enable DECRQSS terminal query (requires `query-detect` feature) // Uses a 100ms timeout by default use termprofile::DefaultTerminal; use std::time::Duration; let terminal = DefaultTerminal::new() .unwrap() .timeout(Duration::from_millis(200)); // custom timeout let settings = DetectorSettings::new().query_terminal(terminal); let profile = TermProfile::detect(&stdout(), settings); println!("Profile (custom query timeout): {profile:?}"); ``` ``` -------------------------------- ### Basic TermProfile Detection Source: https://context7.com/aschey/termprofile/llms.txt Performs basic terminal profile detection using only environment variables, without performing any I/O queries to the terminal. This is a fast, non-intrusive method suitable for initial checks. ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Basic detection using only environment variables (no I/O query) let profile = TermProfile::detect(&stdout(), DetectorSettings::default()); println!("Detected profile: {profile:?}"); // e.g. "Detected profile: TrueColor" ``` -------------------------------- ### Automatic Color Downconversion with `adapt_color` Source: https://context7.com/aschey/termprofile/llms.txt Adapts any `anstyle::Color` to the nearest compatible variant for the current terminal profile. Returns `None` for `NoTty` or `NoColor` profiles. Requires the `convert` feature. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; // On a true-color terminal, RGB passes through unchanged let profile = TermProfile::TrueColor; let rgb: Color = RgbColor(209, 234, 213).into(); assert_eq!(profile.adapt_color(rgb), Some(rgb)); ``` ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; // On an Ansi256 terminal, RGB is mapped to the nearest indexed color let profile = TermProfile::Ansi256; let adapted = profile.adapt_color(rgb); assert_eq!(adapted, Some(Ansi256Color(253).into())); ``` ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; // On an Ansi16 terminal, the Ansi256 color is further mapped to the nearest named color let profile = TermProfile::Ansi16; let ansi256: Color = Ansi256Color(32).into(); let adapted = profile.adapt_color(ansi256); // Returns Some(AnsiColor::Blue) or similar nearest 16-color equivalent ``` ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; // NoTty returns None (no escape sequences should be emitted) let profile = TermProfile::NoTty; assert_eq!(profile.adapt_color(rgb), None); ``` -------------------------------- ### Custom Environment Variable Source for Testing Source: https://context7.com/aschey/termprofile/llms.txt Use an in-memory map as a source for environment variables, enabling deterministic unit tests without modifying the global process state. Essential for testing color-aware code. ```rust use std::collections::HashMap; use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Simulate an xterm-256color terminal let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::Ansi256); ``` ```rust use std::collections::HashMap; use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Simulate a true-color terminal let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ("COLORTERM", "truecolor"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::TrueColor); ``` ```rust use std::collections::HashMap; use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Simulate NO_COLOR override let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ("NO_COLOR", "1"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::NoColor); ``` -------------------------------- ### Color Cache Configuration Source: https://context7.com/aschey/termprofile/llms.txt Enables and configures a global LRU cache for RGB-to-ANSI-256 color conversions to improve performance by memoizing results, trading memory for CPU time. The cache is disabled by default. ```APIDOC ## Color Cache (`color-cache` feature) RGB-to-ANSI-256 conversion uses perceptually-weighted math that can be noticeable at high frame rates. The optional LRU cache memoizes results globally, trading memory for CPU time. The cache is disabled by default even when the feature is compiled in. ```rust // Cargo.toml: termprofile = { features = ["convert", "color-cache"] } use termprofile::{set_color_cache_enabled, set_color_cache_size}; // Enable caching (call once at startup, before any adapt_color calls) set_color_cache_enabled(true); // Optionally resize the cache (default is 256 entries) set_color_cache_size(512.try_into().expect("non-zero size")); // All subsequent adapt_color / rgb_to_ansi256 calls use the cache automatically use termprofile::{TermProfile, rgb_to_ansi256}; use anstyle::RgbColor; let index = rgb_to_ansi256(RgbColor(100, 149, 237)); // cornflower blue println!("ANSI 256 index: {index}"); // 69 ``` ``` -------------------------------- ### TermProfile Detection with DECRQSS Query Source: https://context7.com/aschey/termprofile/llms.txt Enables detection using the DECRQSS terminal query, which directly interrogates the terminal hardware for its capabilities. This requires the `query-detect` feature and should be called before TUI frameworks take control of the terminal. ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Detection with DECRQSS terminal query (requires `query-detect` feature) // IMPORTANT: call this before initializing any TUI framework that takes // ownership of the terminal, as the query temporarily enters raw mode. let profile = TermProfile::detect(&stdout(), DetectorSettings::with_query().unwrap()); println!("Detected profile (with query): {profile:?}"); ``` -------------------------------- ### TermProfile::adapt_style Source: https://context7.com/aschey/termprofile/llms.txt Adapts an entire `anstyle::Style` (foreground, background, and underline color) for the current terminal profile. On `NoTty`, returns a default (empty) style to prevent escape sequence emission. ```APIDOC ## `TermProfile::adapt_style` — Full Style Downconversion (`convert` feature) Adapts an entire `anstyle::Style` (foreground, background, and underline color) for the current profile. On `NoTty`, returns a default (empty) style so that no escape sequences are emitted at all. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, AnsiColor, Style}; let fg: Color = RgbColor(106, 132, 92).into(); let bg: Color = RgbColor(4, 35, 212).into(); let style = Style::new().fg_color(Some(fg)).bg_color(Some(bg)); // Ansi16 profile: both fg and bg are mapped to nearest named colors let profile = TermProfile::Ansi16; let adapted = profile.adapt_style(style); assert_eq!( adapted, Style::new() .fg_color(Some(AnsiColor::Cyan.into())) .bg_color(Some(AnsiColor::BrightBlue.into())) ); // NoTty profile: all styling stripped entirely let no_tty = TermProfile::NoTty; assert_eq!(no_tty.adapt_style(style), Style::default()); ``` ``` -------------------------------- ### Custom Environment Source for Terminal Detection Source: https://github.com/aschey/termprofile/blob/main/README.md Detects terminal profile using a custom in-memory map for environment variables instead of reading from the actual environment. Useful for reproducible tests. ```rust use std::collections::HashMap; use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; let source = HashMap::from_iter([("TERM", "xterm-256color"), ("COLORTERM", "1")]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); let profile = TermProfile::detect_with_vars(vars); println!("Profile: {profile:?}"); ``` -------------------------------- ### Color Cache for RGB-to-ANSI-256 Conversions Source: https://context7.com/aschey/termprofile/llms.txt Enable and configure an LRU cache for RGB-to-ANSI-256 conversions to improve performance at the cost of memory. The cache is disabled by default. Ensure both `convert` and `color-cache` features are enabled. ```rust // Cargo.toml: termprofile = { features = ["convert", "color-cache"] } use termprofile::{set_color_cache_enabled, set_color_cache_size}; // Enable caching (call once at startup, before any adapt_color calls) set_color_cache_enabled(true); // Optionally resize the cache (default is 256 entries) set_color_cache_size(512.try_into().expect("non-zero size")); // All subsequent adapt_color / rgb_to_ansi256 calls use the cache automatically use termprofile::{TermProfile, rgb_to_ansi256}; use anstyle::RgbColor; let index = rgb_to_ansi256(RgbColor(100, 149, 237)); // cornflower blue println!("ANSI 256 index: {index}"); // 69 ``` -------------------------------- ### TermVars::from_source Source: https://context7.com/aschey/termprofile/llms.txt Provides environment variables from an in-memory map instead of `std::env`. This is essential for deterministic unit testing of color-aware code without spawning subprocesses or mutating global process state. ```APIDOC ## `TermVars::from_source` — Custom Environment Variable Source Provides environment variables from an in-memory map instead of `std::env`. Essential for deterministic unit testing of color-aware code without spawning subprocesses or mutating global process state. ```rust use std::collections::HashMap; use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Simulate an xterm-256color terminal let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::Ansi256); // Simulate a true-color terminal let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ("COLORTERM", "truecolor"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::TrueColor); // Simulate NO_COLOR override let source = HashMap::from_iter([ ("TERM", "xterm-256color"), ("NO_COLOR", "1"), ]); let vars = TermVars::from_source(&source, &stdout(), DetectorSettings::default()); assert_eq!(TermProfile::detect_with_vars(vars), TermProfile::NoColor); ``` ``` -------------------------------- ### Adapt RGB Color to ANSI 256 Source: https://github.com/aschey/termprofile/blob/main/README.md Converts an RGB color to its closest ANSI 256 equivalent for terminals with limited color support. Asserts the expected conversion result. ```rust use termprofile::TermProfile; use std::io::stdout; use anstyle::{Color, RgbColor, Ansi256Color}; let profile = TermProfile::Ansi256; let rgb_color: Color = RgbColor(209, 234, 213).into(); let adapted_color = profile.adapt_color(rgb_color); assert_eq!(adapted_color, Some(Ansi256Color(253).into())); ``` -------------------------------- ### Two-Step Terminal Detection with Variable Overrides Source: https://context7.com/aschey/termprofile/llms.txt Collect environment variables first, then override specific settings before detecting the terminal profile. Useful for testing or forcing specific terminal behaviors. ```rust use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Step 1: collect variables from the real environment let mut vars = TermVars::from_env(&stdout(), DetectorSettings::default()); // Step 2: override before detecting vars.overrides.force_color = "truecolor".into(); // force TrueColor // vars.overrides.no_color = "1".into(); // or disable all color // vars.overrides.tty_force = "1".into(); // treat as TTY even when piped // Step 3: detect using the modified variables let profile = TermProfile::detect_with_vars(vars); println!("Profile with override: {profile:?}"); // → "Profile with override: TrueColor" ``` -------------------------------- ### ProfileColor - Fine-Grained Per-Profile Color Control Source: https://context7.com/aschey/termprofile/llms.txt Allows explicit color selection for different terminal capability tiers (true color, ANSI 256, ANSI 16). The correct color variant is automatically selected at runtime based on the active terminal profile. ```APIDOC ## `ProfileColor` — Fine-Grained Per-Profile Color Control (`convert` feature) When automatic RGB-to-nearest-color conversion doesn't produce the best visual result, `ProfileColor` lets you hand-pick the exact color for each capability tier. The correct variant is selected at `adapt()` time based on the active profile. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::{TermProfile, ProfileColor}; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; let profile = TermProfile::Ansi256; // Provide explicit fallback colors for each tier let color = ProfileColor::new( Color::Rgb(RgbColor(209, 234, 213)), // default (true color) profile, ) .ansi_256(Ansi256Color(240)) // use index 240 on 256-color terminals .ansi_16(AnsiColor::White); // use White on 16-color terminals // On Ansi256, the explicit ansi_256 value is returned assert_eq!(color.adapt(), Some(Ansi256Color(240).into())); // On Ansi16 let profile16 = TermProfile::Ansi16; let color16 = ProfileColor::new(Color::Rgb(RgbColor(209, 234, 213)), profile16) .ansi_256(Ansi256Color(240)) .ansi_16(AnsiColor::White); assert_eq!(color16.adapt(), Some(AnsiColor::White.into())); ``` ``` -------------------------------- ### TermProfile Enum Variants and Usage Source: https://context7.com/aschey/termprofile/llms.txt Demonstrates the ordered variants of the `TermProfile` enum, representing different levels of terminal color support. Use comparisons to check capability and a match statement for branching logic. ```rust use termprofile::TermProfile; // Variants in ascending capability order: // TermProfile::NoTty – output is not a terminal; no escape sequences // TermProfile::NoColor – TTY present but colors disabled (e.g. NO_COLOR set) // TermProfile::Ansi16 – 16 standard ANSI colors supported // TermProfile::Ansi256 – 256-color indexed palette supported // TermProfile::TrueColor – full 24-bit RGB supported let profile = TermProfile::TrueColor; assert!(profile > TermProfile::Ansi256); assert!(profile >= TermProfile::Ansi16); assert_eq!(profile, TermProfile::TrueColor); // Branch on capability level match profile { TermProfile::NoTty => println!("piped/non-TTY output — skip all styling"), TermProfile::NoColor => println!("TTY present but NO_COLOR set — text modifiers only"), TermProfile::Ansi16 => println!("16 ANSI colors available"), TermProfile::Ansi256 => println!("256 indexed colors available"), TermProfile::TrueColor => println!("Full RGB / true color available"), } ``` -------------------------------- ### Detect Terminal Color Support Source: https://github.com/aschey/termprofile/blob/main/README.md Detects the terminal's color profile using default settings. Prints the detected profile to standard output. ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; let profile = TermProfile::detect(&stdout(), DetectorSettings::default()); println!("Detected profile: {profile:?}"); ``` -------------------------------- ### ProfileColor for Per-Profile Color Control Source: https://context7.com/aschey/termprofile/llms.txt Use `ProfileColor` to specify exact colors for different terminal capability tiers. The correct variant is selected at `adapt()` time based on the active profile. Ensure the `convert` feature is enabled. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::{TermProfile, ProfileColor}; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; let profile = TermProfile::Ansi256; // Provide explicit fallback colors for each tier let color = ProfileColor::new( Color::Rgb(RgbColor(209, 234, 213)), // default (true color) profile, ) .ansi_256(Ansi256Color(240)) // use index 240 on 256-color terminals .ansi_16(AnsiColor::White); // use White on 16-color terminals // On Ansi256, the explicit ansi_256 value is returned assert_eq!(color.adapt(), Some(Ansi256Color(240).into())); // On Ansi16 let profile16 = TermProfile::Ansi16; let color16 = ProfileColor::new(Color::Rgb(RgbColor(209, 234, 213)), profile16) .ansi_256(Ansi256Color(240)) .ansi_16(AnsiColor::White); assert_eq!(color16.adapt(), Some(AnsiColor::White.into())); ``` -------------------------------- ### TermProfile::detect Source: https://context7.com/aschey/termprofile/llms.txt Automatically detects the color profile of a given output handle by reading environment variables, checking known terminal programs, consulting tmux, and optionally querying the terminal. ```APIDOC ## `TermProfile::detect` — Automatic Profile Detection Detects the color profile of a given output handle by reading environment variables, checking known terminal programs, consulting tmux, and optionally querying the terminal via DECRQSS. This is an expensive operation — call it once at startup and reuse the result. ```rust use std::io::stdout; use termprofile::{TermProfile, DetectorSettings}; // Basic detection using only environment variables (no I/O query) let profile = TermProfile::detect(&stdout(), DetectorSettings::default()); println!("Detected profile: {profile:?}"); // e.g. "Detected profile: TrueColor" // Detection with DECRQSS terminal query (requires `query-detect` feature) // IMPORTANT: call this before initializing any TUI framework that takes // ownership of the terminal, as the query temporarily enters raw mode. let profile = TermProfile::detect(&stdout(), DetectorSettings::with_query().unwrap()); println!("Detected profile (with query): {profile:?}"); ``` ``` -------------------------------- ### TermProfile::adapt_color Source: https://context7.com/aschey/termprofile/llms.txt Automatically adapts any `anstyle::Color` to the nearest compatible variant for the current terminal profile. Returns `None` when the profile is `NoTty` or `NoColor`. RGB colors are converted perceptually. ```APIDOC ## `TermProfile::adapt_color` — Automatic Color Downconversion (`convert` feature) Adapts any `anstyle::Color` (or Ratatui `Color` with the `ratatui` feature) to the nearest compatible variant for the current profile. Returns `None` when the profile is `NoTty` or `NoColor`. RGB colors are converted to the nearest ANSI 256 entry, and then to the nearest ANSI 16 color, using perceptually-weighted distance calculations. ```rust // Cargo.toml: termprofile = { features = ["convert"] } use termprofile::TermProfile; use anstyle::{Color, RgbColor, Ansi256Color, AnsiColor}; // On a true-color terminal, RGB passes through unchanged let profile = TermProfile::TrueColor; let rgb: Color = RgbColor(209, 234, 213).into(); assert_eq!(profile.adapt_color(rgb), Some(rgb)); // On an Ansi256 terminal, RGB is mapped to the nearest indexed color let profile = TermProfile::Ansi256; let adapted = profile.adapt_color(rgb); assert_eq!(adapted, Some(Ansi256Color(253).into())); // On an Ansi16 terminal, the Ansi256 color is further mapped to the nearest named color let profile = TermProfile::Ansi16; let ansi256: Color = Ansi256Color(32).into(); let adapted = profile.adapt_color(ansi256); // Returns Some(AnsiColor::Blue) or similar nearest 16-color equivalent // NoTty returns None (no escape sequences should be emitted) let profile = TermProfile::NoTty; assert_eq!(profile.adapt_color(rgb), None); ``` ``` -------------------------------- ### TermVars and TermProfile::detect_with_vars Source: https://context7.com/aschey/termprofile/llms.txt Separates variable collection from detection, allowing inspection or mutation of collected environment variables before running detection logic. This is useful for testing or forcing specific behavior at runtime. ```APIDOC ## `TermVars` and `TermProfile::detect_with_vars` — Two-Step Detection with Variable Overrides Separates variable collection from detection, allowing you to inspect or mutate the collected environment variables before running detection logic. Useful for testing or for forcing specific behavior at runtime. ```rust use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; // Step 1: collect variables from the real environment let mut vars = TermVars::from_env(&stdout(), DetectorSettings::default()); // Step 2: override before detecting vars.overrides.force_color = "truecolor".into(); // force TrueColor // vars.overrides.no_color = "1".into(); // or disable all color // vars.overrides.tty_force = "1".into(); // treat as TTY even when piped // Step 3: detect using the modified variables let profile = TermProfile::detect_with_vars(vars); println!("Profile with override: {profile:?}"); // → "Profile with override: TrueColor" ``` ``` -------------------------------- ### Force TTY Behavior in Subprocesses with TTY_FORCE Source: https://context7.com/aschey/termprofile/llms.txt When spawning a subprocess that pipes its output, set `TTY_FORCE=1` in the child's environment to make termprofile treat its output as a TTY for normal color detection. ```rust use std::process::{Command, Stdio}; // Run a color-aware child program and capture its styled output let child = Command::new("my-cli-tool") .stdout(Stdio::piped()) .env("TTY_FORCE", "1") // tell the child: act as if stdout is a TTY .env("FORCE_COLOR", "truecolor") // optionally force a specific color level .spawn() .expect("failed to spawn"); let output = child.wait_with_output().expect("failed to wait"); println!("{}", String::from_utf8_lossy(&output.stdout)); ``` -------------------------------- ### Implement Custom QueryTerminal in Rust Source: https://context7.com/aschey/termprofile/llms.txt Implement the `QueryTerminal` trait to integrate with custom terminal abstractions like test harnesses or remote terminals. This involves providing raw-mode and event-reading logic. ```rust use std::io; use termprofile::{QueryTerminal, DcsEvent, DetectorSettings, TermProfile, IsTerminal}; struct MyTerminal { // your terminal handle here } impl io::Write for MyTerminal { fn write(&mut self, buf: &[u8]) -> io::Result { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } impl QueryTerminal for MyTerminal { fn setup(&mut self) -> io::Result<()> { // enter raw mode on your terminal Ok(()) } fn cleanup(&mut self) -> io::Result<()> { // restore cooked mode Ok(()) } fn read_event(&mut self) -> io::Result { // parse the DECRQSS response from your terminal // return DcsEvent::BackgroundColor(rgb) when the test color is echoed back, // DcsEvent::DeviceAttributes when the DA1 response arrives, // or DcsEvent::TimedOut if nothing arrives within your timeout Ok(DcsEvent::TimedOut) } } impl IsTerminal for MyTerminal { fn is_terminal(&self) -> bool { true } } // Wire it up let my_term = MyTerminal {}; let settings = DetectorSettings::new().query_terminal(my_term); use std::io::stdout; let profile = TermProfile::detect(&stdout(), settings); ``` -------------------------------- ### TermProfile Enum Source: https://context7.com/aschey/termprofile/llms.txt The core type representing the detected color capability of a terminal. Variants are ordered from least to most capable, enabling comparisons. ```APIDOC ## TermProfile Enum The core type representing the detected (or manually specified) color capability of a terminal. Variants are ordered from least to most capable, enabling comparisons like `profile >= TermProfile::Ansi256`. It is `Copy`, `Clone`, `Debug`, `PartialOrd`, and `Ord`. ```rust use termprofile::TermProfile; // Variants in ascending capability order: // TermProfile::NoTty – output is not a terminal; no escape sequences // TermProfile::NoColor – TTY present but colors disabled (e.g. NO_COLOR set) // TermProfile::Ansi16 – 16 standard ANSI colors supported // TermProfile::Ansi256 – 256-color indexed palette supported // TermProfile::TrueColor – full 24-bit RGB supported let profile = TermProfile::TrueColor; assert!(profile > TermProfile::Ansi256); assert!(profile >= TermProfile::Ansi16); assert_eq!(profile, TermProfile::TrueColor); // Branch on capability level match profile { TermProfile::NoTty => println!("piped/non-TTY output — skip all styling"), TermProfile::NoColor => println!("TTY present but NO_COLOR set — text modifiers only"), TermProfile::Ansi16 => println!("16 ANSI colors available"), TermProfile::Ansi256 => println!("256 indexed colors available"), TermProfile::TrueColor => println!("Full RGB / true color available"), } ``` ``` -------------------------------- ### Override Terminal Variables for Detection Source: https://github.com/aschey/termprofile/blob/main/README.md Forces a specific color support level by overriding environment variables before detection. Useful for testing or specific environments. ```rust use std::io::stdout; use termprofile::{TermProfile, TermVars, DetectorSettings}; let mut vars = TermVars::from_env(&stdout(), DetectorSettings::default()); vars.overrides.force_color = "1".into(); let profile = TermProfile::detect_with_vars(vars); println!("Profile with override: {profile:?}"); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.