owo-colors-4.2.3/.cargo_vcs_info.json0000644000000001360000000000100131450ustar { "git": { "sha1": "c0de470adcc04024c562ab055972e0c77cfa9a62" }, "path_in_vcs": "" }owo-colors-4.2.3/.github/dependabot.yml000064400000000000000000000011121046102023000161200ustar 00000000000000version: 2 updates: # Fetch and update latest `cargo` packages - package-ecosystem: "cargo" directory: "/" schedule: interval: daily time: "00:00" open-pull-requests-limit: 10 commit-message: prefix: build prefix-development: build include: scope # Fetch and update latest `github-actions` pkgs - package-ecosystem: github-actions directory: "/" schedule: interval: daily time: "00:00" open-pull-requests-limit: 10 commit-message: prefix: build prefix-development: build include: scope owo-colors-4.2.3/.github/workflows/ci.yml000064400000000000000000000032001046102023000164430ustar 00000000000000name: Continuous Integration on: push: branches: - main pull_request: branches: - main paths-ignore: - "README.md" jobs: fmt: name: Source formatting check runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: rustfmt - name: Check formatting run: cargo fmt --check build: name: Lint and test check strategy: fail-fast: false matrix: rust: ["1.70.0", "stable", "nightly"] os: ["ubuntu-latest", "windows-latest", "macos-latest"] runs-on: ${{ matrix.os }} steps: - name: Checkout sources uses: actions/checkout@v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} components: clippy - name: Restore cargo cache uses: Swatinem/rust-cache@v2 - name: Run lints run: cargo clippy -- -D warnings - name: Run tests run: | cargo test --all-targets --all-features cargo test --all-targets --no-default-features - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - name: Run tests with feature powerset # Note: you might think that we can also pass in `--exclude-all-features` here, but that # isn't the case because if you pass in a --example, it doesn't run doctests. The below # expression will run doctests as well. run: cargo hack test --feature-powerset owo-colors-4.2.3/.github/workflows/release.yml000064400000000000000000000016461046102023000175040ustar 00000000000000name: Publish releases to GitHub on: push: tags: - "*" jobs: datatest-stable-release: if: github.repository_owner == 'owo-colors' && startsWith(github.ref_name, 'v') runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 with: persist-credentials: false - uses: taiki-e/install-action@v2 with: tool: cargo-release@0.25 - uses: taiki-e/create-gh-release-action@v1 with: changelog: CHANGELOG.md title: owo-colors $version branch: main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: ./scripts/cargo-release-publish.sh env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} owo-colors-4.2.3/.gitignore000064400000000000000000000000231046102023000137200ustar 00000000000000/target Cargo.lock owo-colors-4.2.3/CHANGELOG.md000064400000000000000000000044141046102023000135510ustar 00000000000000# Changelog ## [4.2.3] - 2025-09-29 ### Fixed Replaced obsolete `doc_auto_cfg` with `doc_cfg`, to fix Rust nightly builds with the `doc_cfg` flag enabled. ## [4.2.2] - 2025-06-23 ### Fixed Fixed applying a background color and a text effect (like underline or italic) at the same time ([#145]). [#145]: https://github.com/owo-colors/owo-colors/issues/145 ## [4.2.1] - 2025-05-15 ### Fixed - Fixed a couple of bugs while rendering custom colors ([#144]). Thanks [https://github.com/MiguelValentine](@MiguelValentine) for your first contribution! [#144]: https://github.com/owo-colors/owo-colors/pull/144 ## [4.2.0] - 2025-02-22 ### Added - `Style::prefix_formatter` and `Style::suffix_formatter` return `Display` formatters for the prefix and the suffix of a style, respectively. - All the `*Display` types now have an `into_styled` function that converts those types into a `Styled`, erasing type parameters. - Even more methods are now `const`. ### Changed - The `Color` and `DynColor` traits are now explicitly marked sealed (i.e. downstream crates cannot implement them). These traits were already effectively sealed due to a number of hidden methods that were not part of the API, but they are now explicitly so. In that sense this is not a breaking change, so it's being released under a new minor version rather than a major version. ## [4.1.1] - 2025-02-22 ### Added - The vast majority of owo-colors is now usable in const contexts. ### Fixed - Documentation for `Stream` is now rendered properly. Thanks [purplesyringa](https://github.com/purplesyringa) for the contribution! - Replace brittle const-promotion-based unsafe code with safe code. Thanks [Manish](https://github.com/Manishearth) for the contribution! ### Other - owo-colors now lives under its own organization, https://github.com/owo-colors. [4.2.3]: https://github.com/owo-colors/owo-colors/releases/tag/v4.2.3 [4.2.2]: https://github.com/owo-colors/owo-colors/releases/tag/v4.2.2 [4.2.1]: https://github.com/owo-colors/owo-colors/releases/tag/v4.2.1 [4.2.0]: https://github.com/owo-colors/owo-colors/releases/tag/v4.2.0 [4.1.1]: https://github.com/owo-colors/owo-colors/releases/tag/v4.1.1 For information about earlier versions, see [the commit history](https://github.com/jam1garner/owo-colors/commits/master). owo-colors-4.2.3/Cargo.lock0000644000000073350000000000100111300ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "hermit-abi" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "is-terminal" version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", "windows-sys", ] [[package]] name = "is_ci" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "libc" version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "owo-colors" version = "4.2.3" dependencies = [ "supports-color 2.1.0", "supports-color 3.0.2", ] [[package]] name = "supports-color" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" dependencies = [ "is-terminal", "is_ci", ] [[package]] name = "supports-color" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" dependencies = [ "is_ci", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" owo-colors-4.2.3/Cargo.toml0000644000000042030000000000100111420ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.70" name = "owo-colors" version = "4.2.3" authors = ["jam1garner <8260240+jam1garner@users.noreply.github.com>"] build = "build.rs" autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Zero-allocation terminal colors that'll make people go owo" documentation = "https://docs.rs/owo-colors" readme = "README.md" keywords = [ "cli", "color", "no-std", "terminal", "ansi_term", ] categories = [ "command-line-interface", "no-std::no-alloc", ] license = "MIT" repository = "https://github.com/owo-colors/owo-colors" [package.metadata.docs.rs] all-features = true rustdoc-args = [ "--cfg", "doc_cfg", ] [features] alloc = [] supports-colors = [ "dep:supports-color-2", "supports-color", ] [lib] name = "owo_colors" path = "src/lib.rs" [[example]] name = "all_xterm_colors" path = "examples/all_xterm_colors.rs" [[example]] name = "banner" path = "examples/banner.rs" [[example]] name = "colors" path = "examples/colors.rs" [[example]] name = "const_colors" path = "examples/const_colors.rs" [[example]] name = "custom_colors" path = "examples/custom_colors.rs" [[example]] name = "dyn_colors" path = "examples/dyn_colors.rs" [[example]] name = "extra_colors" path = "examples/extra_colors.rs" [[example]] name = "override" path = "examples/override.rs" required-features = ["supports-colors"] [[example]] name = "supports_color" path = "examples/supports_color.rs" required-features = ["supports-colors"] [dependencies.supports-color] version = "3.0.0" optional = true [dependencies.supports-color-2] version = "2.0" optional = true package = "supports-color" owo-colors-4.2.3/Cargo.toml.orig000064400000000000000000000023341046102023000146260ustar 00000000000000[package] name = "owo-colors" version = "4.2.3" rust-version = "1.70" authors = ["jam1garner <8260240+jam1garner@users.noreply.github.com>"] edition = "2021" documentation = "https://docs.rs/owo-colors" repository = "https://github.com/owo-colors/owo-colors" description = "Zero-allocation terminal colors that'll make people go owo" license = "MIT" readme = "README.md" keywords = ["cli", "color", "no-std", "terminal", "ansi_term"] categories = ["command-line-interface", "no-std::no-alloc"] [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "doc_cfg"] [[example]] name = "supports_color" required-features = ["supports-colors"] [[example]] name = "override" required-features = ["supports-colors"] [features] # Enable conversions from all versions of supports-color, but only use the latest to determine if # colors are actually supported. # # Don't use dep:supports-color because it's possible there's a broken crate in the wild which uses # the nonfunctional "supports-color" feature. supports-colors = ["dep:supports-color-2", "supports-color"] alloc = [] [dependencies] supports-color-2 = { package = "supports-color", version = "2.0", optional = true } supports-color = { version = "3.0.0", optional = true } owo-colors-4.2.3/LICENSE000064400000000000000000000021041046102023000127370ustar 00000000000000MIT License Copyright (c) 2020 - present The owo-colors Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. owo-colors-4.2.3/README.md000064400000000000000000000071021046102023000132140ustar 00000000000000# Colors [![Current Crates.io Version](https://img.shields.io/crates/v/owo-colors.svg)](https://crates.io/crates/owo-colors) [![docs-rs](https://docs.rs/owo-colors/badge.svg)](https://docs.rs/owo-colors) ![MSRV 1.70+](https://img.shields.io/badge/rustc-1.70+-blue.svg) ![Downloads](https://img.shields.io/crates/d/owo-colors) A zero-allocation no_std-compatible zero-cost way to add color to your Rust terminal to make people go owo. **Supports:** - [x] All std/core formatters - [x] [Display](https://doc.rust-lang.org/std/fmt/trait.Display.html) - [x] [Debug](https://doc.rust-lang.org/std/fmt/trait.Debug.html) - [x] [Octal](https://doc.rust-lang.org/std/fmt/trait.Octal.html) - [x] [LowerHex](https://doc.rust-lang.org/std/fmt/trait.LowerHex.html) - [x] [UpperHex](https://doc.rust-lang.org/std/fmt/trait.UpperHex.html) - [x] [Pointer](https://doc.rust-lang.org/std/fmt/trait.Pointer.html) - [x] [Binary](https://doc.rust-lang.org/std/fmt/trait.Binary.html) - [x] [LowerExp](https://doc.rust-lang.org/std/fmt/trait.LowerExp.html) - [x] [UpperExp](https://doc.rust-lang.org/std/fmt/trait.UpperExp.html) - [x] Optional checking for if a terminal supports colors - [x] Enabled for CI - [x] Disabled by default for non-terminal outputs - [x] Overridable by `NO_COLOR`/`FORCE_COLOR` environment variables - [x] Overridable programmatically via [`set_override`](https://docs.rs/owo-colors/latest/owo_colors/fn.set_override.html) - [x] Dependency-less by default - [x] 100% safe code - [x] Most functions are `const` - [x] Hand picked names for all ANSI (4-bit) and Xterm (8-bit) colors - [x] Support for RGB colors - [x] Set colors at compile time by generics or at runtime by value - [x] All ANSI colors - [x] Basic support (normal and bright variants) - [x] Xterm support (high compatibility and 256 colors) - [x] Truecolor support (modern, 48-bit color) - [x] Styling (underline, strikethrough, etc) owo-colors is also more-or-less a drop-in replacement for [colored](https://crates.io/crates/colored), allowing colored to work in a no_std environment. No allocations or dependencies required because embedded systems deserve to be pretty too uwu. To add to your Cargo.toml: ```toml owo-colors = "4" ``` ## Example ```rust use owo_colors::OwoColorize; fn main() { // Foreground colors println!("My number is {:#x}!", 10.green()); // Background colors println!("My number is not {}!", 4.on_red()); } ``` ## Generic colors ```rust use owo_colors::OwoColorize; use owo_colors::colors::*; fn main() { // Generically color println!("My number might be {}!", 4.fg::().bg::()); } ``` ## Stylize ```rust use owo_colors::OwoColorize; println!("{}", "strikethrough".strikethrough()); ``` ## Only Style on Supported Terminals ```rust use owo_colors::{OwoColorize, Stream::Stdout}; println!( "{}", "colored blue if a supported terminal" .if_supports_color(Stdout, |text| text.bright_blue()) ); ``` Supports `NO_COLOR`/`FORCE_COLOR` environment variables, checks if it's a tty, checks if it's running in CI (and thus likely supports color), and checks which terminal is being used. (Note: requires `supports-colors` feature) ## Minimum supported Rust version (MSRV) The MSRV of owo-colors is **Rust 1.70**. This library has a conservative MSRV policy — Rust versions from the last 12 months will be supported (features available in newer versions will be gated by `build.rs`), the MSRV will only be bumped if required, and if the MSRV is bumped it will always occur with a new minor version. owo-colors-4.2.3/build.rs000064400000000000000000000031411046102023000134010ustar 00000000000000use std::{env, process::Command, str}; fn main() { // Once the MSRV is 1.74, we can replace this with a lint in Cargo.toml instead. println!("cargo:rustc-check-cfg=cfg(doc_cfg)"); println!("cargo:rustc-check-cfg=cfg(const_mut_refs)"); // Rust 1.83+ support &mut in const fn. if let Some(compiler) = rustc_version() { if compiler.is_newer_than_minor(83) { println!("cargo:rustc-cfg=const_mut_refs"); } } } struct Compiler { minor: u32, channel: ReleaseChannel, } impl Compiler { fn is_newer_than_minor(&self, minor: u32) -> bool { match self.channel { ReleaseChannel::Stable | ReleaseChannel::Beta => self.minor >= minor, ReleaseChannel::Nightly => { // Early nightly versions might not have stabilized the feature // yet. self.minor > minor } } } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum ReleaseChannel { Stable, Beta, Nightly, } fn rustc_version() -> Option { let rustc = env::var_os("RUSTC")?; let output = Command::new(rustc).arg("--version").output().ok()?; let version = str::from_utf8(&output.stdout).ok()?; let mut pieces = version.split('.'); if pieces.next() != Some("rustc 1") { return None; } let minor = pieces.next()?.parse().ok()?; let channel = if version.contains("nightly") { ReleaseChannel::Nightly } else if version.contains("beta") { ReleaseChannel::Beta } else { ReleaseChannel::Stable }; Some(Compiler { minor, channel }) } owo-colors-4.2.3/examples/all_xterm_colors.rs000064400000000000000000000276671046102023000175130ustar 00000000000000use owo_colors::OwoColorize; use owo_colors::colors::xterm; macro_rules! xterm_colors { ($( $xterm_num:literal $name:ident ($r:literal, $g:literal, $b:literal) )*) => { $( println!( "{} {}", " ".bg::(), stringify!($name).fg::(), ); )* }; } fn main() { // This example is intended as a quick way to view all the available xterm colors // // ``` // cargo run --example all_xterm_colors // ``` xterm_colors! { 0 UserBlack (0,0,0) 1 UserRed (128,0,0) 2 UserGreen (0,128,0) 3 UserYellow (128,128,0) 4 UserBlue (0,0,128) 5 UserMagenta (128,0,128) 6 UserCyan (0,128,128) 7 UserWhite (192,192,192) 8 UserBrightBlack (128,128,128) 9 UserBrightRed (255,0,0) 10 UserBrightGreen (0,255,0) 11 UserBrightYellow (255,255,0) 12 UserBrightBlue (0,0,255) 13 UserBrightMagenta (255,0,255) 14 UserBrightCyan (0,255,255) 15 UserBrightWhite (255,255,255) 16 Black (0,0,0) 17 StratosBlue (0,0,95) 18 NavyBlue (0,0,135) 19 MidnightBlue (0,0,175) 20 DarkBlue (0,0,215) 21 Blue (0,0,255) 22 CamaroneGreen (0,95,0) 23 BlueStone (0,95,95) 24 OrientBlue (0,95,135) 25 EndeavourBlue (0,95,175) 26 ScienceBlue (0,95,215) 27 BlueRibbon (0,95,255) 28 JapaneseLaurel (0,135,0) 29 DeepSeaGreen (0,135,95) 30 Teal (0,135,135) 31 DeepCerulean (0,135,175) 32 LochmaraBlue (0,135,215) 33 AzureRadiance (0,135,255) 34 LightJapaneseLaurel (0,175,0) 35 Jade (0,175,95) 36 PersianGreen (0,175,135) 37 BondiBlue (0,175,175) 38 Cerulean (0,175,215) 39 LightAzureRadiance (0,175,255) 40 DarkGreen (0,215,0) 41 Malachite (0,215,95) 42 CaribbeanGreen (0,215,135) 43 LightCaribbeanGreen (0,215,175) 44 RobinEggBlue (0,215,215) 45 Aqua (0,215,255) 46 Green (0,255,0) 47 DarkSpringGreen (0,255,95) 48 SpringGreen (0,255,135) 49 LightSpringGreen (0,255,175) 50 BrightTurquoise (0,255,215) 51 Cyan (0,255,255) 52 Rosewood (95,0,0) 53 PompadourMagenta (95,0,95) 54 PigmentIndigo (95,0,135) 55 DarkPurple (95,0,175) 56 ElectricIndigo (95,0,215) 57 ElectricPurple (95,0,255) 58 VerdunGreen (95,95,0) 59 ScorpionOlive (95,95,95) 60 Lilac (95,95,135) 61 ScampiIndigo (95,95,175) 62 Indigo (95,95,215) 63 DarkCornflowerBlue (95,95,255) 64 DarkLimeade (95,135,0) 65 GladeGreen (95,135,95) 66 JuniperGreen (95,135,135) 67 HippieBlue (95,135,175) 68 HavelockBlue (95,135,215) 69 CornflowerBlue (95,135,255) 70 Limeade (95,175,0) 71 FernGreen (95,175,95) 72 SilverTree (95,175,135) 73 Tradewind (95,175,175) 74 ShakespeareBlue (95,175,215) 75 DarkMalibuBlue (95,175,255) 76 DarkBrightGreen (95,215,0) 77 DarkPastelGreen (95,215,95) 78 PastelGreen (95,215,135) 79 DownyTeal (95,215,175) 80 Viking (95,215,215) 81 MalibuBlue (95,215,255) 82 BrightGreen (95,255,0) 83 DarkScreaminGreen (95,255,95) 84 ScreaminGreen (95,255,135) 85 DarkAquamarine (95,255,175) 86 Aquamarine (95,255,215) 87 LightAquamarine (95,255,255) 88 Maroon (135,0,0) 89 DarkFreshEggplant (135,0,95) 90 LightFreshEggplant (135,0,135) 91 Purple (135,0,175) 92 ElectricViolet (135,0,215) 93 LightElectricViolet (135,0,255) 94 Brown (135,95,0) 95 CopperRose (135,95,95) 96 StrikemasterPurple (135,95,135) 97 DelugePurple (135,95,175) 98 DarkMediumPurple (135,95,215) 99 DarkHeliotropePurple (135,95,255) 100 Olive (135,135,0) 101 ClayCreekOlive (135,135,95) 102 DarkGray (135,135,135) 103 WildBlueYonder (135,135,175) 104 ChetwodeBlue (135,135,215) 105 SlateBlue (135,135,255) 106 LightLimeade (135,175,0) 107 ChelseaCucumber (135,175,95) 108 BayLeaf (135,175,135) 109 GulfStream (135,175,175) 110 PoloBlue (135,175,215) 111 LightMalibuBlue (135,175,255) 112 Pistachio (135,215,0) 113 LightPastelGreen (135,215,95) 114 DarkFeijoaGreen (135,215,135) 115 VistaBlue (135,215,175) 116 Bermuda (135,215,215) 117 DarkAnakiwaBlue (135,215,255) 118 ChartreuseGreen (135,255,0) 119 LightScreaminGreen (135,255,95) 120 DarkMintGreen (135,255,135) 121 MintGreen (135,255,175) 122 LighterAquamarine (135,255,215) 123 AnakiwaBlue (135,255,255) 124 BrightRed (175,0,0) 125 DarkFlirt (175,0,95) 126 Flirt (175,0,135) 127 LightFlirt (175,0,175) 128 DarkViolet (175,0,215) 129 BrightElectricViolet (175,0,255) 130 RoseofSharonOrange (175,95,0) 131 MatrixPink (175,95,95) 132 TapestryPink (175,95,135) 133 FuchsiaPink (175,95,175) 134 MediumPurple (175,95,215) 135 Heliotrope (175,95,255) 136 PirateGold (175,135,0) 137 MuesliOrange (175,135,95) 138 PharlapPink (175,135,135) 139 Bouquet (175,135,175) 140 Lavender (175,135,215) 141 LightHeliotrope (175,135,255) 142 BuddhaGold (175,175,0) 143 OliveGreen (175,175,95) 144 HillaryOlive (175,175,135) 145 SilverChalice (175,175,175) 146 WistfulLilac (175,175,215) 147 MelroseLilac (175,175,255) 148 RioGrandeGreen (175,215,0) 149 ConiferGreen (175,215,95) 150 Feijoa (175,215,135) 151 PixieGreen (175,215,175) 152 JungleMist (175,215,215) 153 LightAnakiwaBlue (175,215,255) 154 Lime (175,255,0) 155 GreenYellow (175,255,95) 156 LightMintGreen (175,255,135) 157 Celadon (175,255,175) 158 AeroBlue (175,255,215) 159 FrenchPassLightBlue (175,255,255) 160 GuardsmanRed (215,0,0) 161 RazzmatazzCerise (215,0,95) 162 MediumVioletRed (215,0,135) 163 HollywoodCerise (215,0,175) 164 DarkPurplePizzazz (215,0,215) 165 BrighterElectricViolet (215,0,255) 166 TennOrange (215,95,0) 167 RomanOrange (215,95,95) 168 CranberryPink (215,95,135) 169 HopbushPink (215,95,175) 170 Orchid (215,95,215) 171 LighterHeliotrope (215,95,255) 172 MangoTango (215,135,0) 173 Copperfield (215,135,95) 174 SeaPink (215,135,135) 175 CanCanPink (215,135,175) 176 LightOrchid (215,135,215) 177 BrightHeliotrope (215,135,255) 178 DarkCorn (215,175,0) 179 DarkTachaOrange (215,175,95) 180 TanBeige (215,175,135) 181 ClamShell (215,175,175) 182 ThistlePink (215,175,215) 183 Mauve (215,175,255) 184 Corn (215,215,0) 185 TachaOrange (215,215,95) 186 DecoOrange (215,215,135) 187 PaleGoldenrod (215,215,175) 188 AltoBeige (215,215,215) 189 FogPink (215,215,255) 190 ChartreuseYellow (215,255,0) 191 Canary (215,255,95) 192 Honeysuckle (215,255,135) 193 ReefPaleYellow (215,255,175) 194 SnowyMint (215,255,215) 195 OysterBay (215,255,255) 196 Red (255,0,0) 197 DarkRose (255,0,95) 198 Rose (255,0,135) 199 LightHollywoodCerise (255,0,175) 200 PurplePizzazz (255,0,215) 201 Fuchsia (255,0,255) 202 BlazeOrange (255,95,0) 203 BittersweetOrange (255,95,95) 204 WildWatermelon (255,95,135) 205 DarkHotPink (255,95,175) 206 HotPink (255,95,215) 207 PinkFlamingo (255,95,255) 208 FlushOrange (255,135,0) 209 Salmon (255,135,95) 210 VividTangerine (255,135,135) 211 PinkSalmon (255,135,175) 212 DarkLavenderRose (255,135,215) 213 BlushPink (255,135,255) 214 YellowSea (255,175,0) 215 TexasRose (255,175,95) 216 Tacao (255,175,135) 217 Sundown (255,175,175) 218 CottonCandy (255,175,215) 219 LavenderRose (255,175,255) 220 Gold (255,215,0) 221 Dandelion (255,215,95) 222 GrandisCaramel (255,215,135) 223 Caramel (255,215,175) 224 CosmosSalmon (255,215,215) 225 PinkLace (255,215,255) 226 Yellow (255,255,0) 227 LaserLemon (255,255,95) 228 DollyYellow (255,255,135) 229 PortafinoYellow (255,255,175) 230 Cumulus (255,255,215) 231 White (255,255,255) 232 DarkCodGray (8,8,8) 233 CodGray (18,18,18) 234 LightCodGray (28,28,28) 235 DarkMineShaft (38,38,38) 236 MineShaft (48,48,48) 237 LightMineShaft (58,58,58) 238 DarkTundora (68,68,68) 239 Tundora (78,78,78) 240 ScorpionGray (88,88,88) 241 DarkDoveGray (98,98,98) 242 DoveGray (108,108,108) 243 Boulder (118,118,118) 244 Gray (128,128,128) 245 LightGray (138,138,138) 246 DustyGray (148,148,148) 247 NobelGray (158,158,158) 248 DarkSilverChalice (168,168,168) 249 LightSilverChalice (178,178,178) 250 DarkSilver (188,188,188) 251 Silver (198,198,198) 252 DarkAlto (208,208,208) 253 Alto (218,218,218) 254 Mercury (228,228,228) 255 GalleryGray (238,238,238) } } owo-colors-4.2.3/examples/banner.rs000064400000000000000000000033661046102023000153760ustar 00000000000000use owo_colors::{DynColors, OwoColorize}; const OWO: &str = r#" ██████╗ ██╗ ██╗ ██████╗ ██╔═══██╗██║ ██║██╔═══██╗ ██║ ██║██║ █╗ ██║██║ ██║ ██║ ██║██║███╗██║██║ ██║ ╚██████╔╝╚███╔███╔╝╚██████╔╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ "#; const COLORS: &str = r#" .o88b. | .d88b. |db | .d88b. |d8888b. |.d8888. d8P Y8 |.8P Y8. |88 |.8P Y8. |88 `8D |88' YP 8P |88 88 |88 |88 88 |88oobY' |`8bo. 8b |88 88 |88 |88 88 |88`8b | `Y8b. Y8b d8 |`8b d8' |88booo. |`8b d8' |88 `88. |db 8D `Y88P' | `Y88P' |Y88888P | `Y88P' |88 YD |`8888Y' "#; fn main() { let colors: [DynColors; 6] = [ "#B80A41", "#4E4BA8", "#6EB122", "#DAAC06", "#00938A", "#E23838", ] .map(|color| color.parse().unwrap()); println!("\n\n\n\n\n{}", OWO.fg_rgb::<0x2E, 0x31, 0x92>().bold()); for line in COLORS.split_inclusive('\n') { for (text, color) in line.split('|').zip(colors.iter().copied()) { print!("{}", text.color(color).bold()); } } println!("\n\n\n\n\n\n"); } owo-colors-4.2.3/examples/colors.rs000064400000000000000000000024751046102023000154320ustar 00000000000000use owo_colors::{OwoColorize, colors::*}; fn main() { // normal usage println!("{}", "green".green()); println!("{}", "yellow".yellow()); println!("{}", "blue".blue()); println!("{}", "black".black()); // generic examples println!("{}", "red".fg::()); println!("{}", "magenta".fg::()); println!("{}", "white".fg::()); println!("{}", "cyan".fg::()); println!("\nBrights\n-------"); println!("{}", "green".fg::()); println!("{}", "yellow".fg::()); println!("{}", "blue".fg::()); println!("{}", "black".fg::()); println!("{}", "red".fg::()); println!("{}", "magenta".fg::()); println!("{}", "white".fg::()); println!("{}", "cyan".fg::()); println!("\nStyles\n-------"); println!("{}", "underline".underline()); println!("{}", "bold".bold()); println!("{}", "italic".italic()); println!("{}", "strikethrough".strikethrough()); println!("{}", "reverse".reversed()); println!("1{}3", "2".hidden()); println!("{}", "blink".blink()); println!("{}", "blink fast".blink_fast()); // foreground and background let red_on_white = "red on white".red().on_white(); println!("{}", red_on_white); } owo-colors-4.2.3/examples/const_colors.rs000064400000000000000000000047611046102023000166400ustar 00000000000000//! Example demonstrating colors in const contexts. use owo_colors::{colors::*, styles::*, *}; const GREEN_TEXT: FgColorDisplay = FgColorDisplay::new("green text"); const RED_BG_TEXT: BgColorDisplay = BgColorDisplay::new("red background"); const COMBO_TEXT: ComboColorDisplay = ComboColorDisplay::new("blue text on white background"); const DYN_RED_TEXT: FgDynColorDisplay = FgDynColorDisplay::new("red text (dynamic)", AnsiColors::Red); const DYN_GREEN_BG_TEXT: BgDynColorDisplay = BgDynColorDisplay::new("green background (dynamic)", AnsiColors::Green); const COMBO_DYN_TEXT: ComboDynColorDisplay = ComboDynColorDisplay::new( "blue text on lilac background (dynamic)", XtermColors::BlueRibbon, XtermColors::WistfulLilac, ); const BOLD_TEXT: BoldDisplay = BoldDisplay("bold text"); const DIM_TEXT: DimDisplay = DimDisplay("dim text"); const ITALIC_TEXT: ItalicDisplay = ItalicDisplay("italic text"); const UNDERLINE_TEXT: UnderlineDisplay = UnderlineDisplay("underlined text"); const BLINK_TEXT: BlinkDisplay = BlinkDisplay("blinking text"); const BLINK_FAST_TEXT: BlinkFastDisplay = BlinkFastDisplay("fast blinking text"); const REVERSED_TEXT: ReversedDisplay = ReversedDisplay("reversed text"); const HIDDEN_TEXT: HiddenDisplay = HiddenDisplay("hidden text"); const STRIKETHROUGH_TEXT: StrikeThroughDisplay = StrikeThroughDisplay("strikethrough text"); const STYLED_TEXT: Styled<&'static str> = Style::new() .bold() .italic() .red() .style("bold and italic red text (dynamically styled)"); const STYLED_TEXT_2: Styled<&'static str> = Style::new() .effect(Effect::Underline) .effects(&[Effect::Dimmed, Effect::Strikethrough]) .green() .style("underlined, dimmed and strikethrough green text (dynamically styled)"); fn main() { println!("{}", GREEN_TEXT); println!("{}", RED_BG_TEXT); println!("{}", COMBO_TEXT); println!("{}", DYN_RED_TEXT); println!("{}", DYN_GREEN_BG_TEXT); println!("{}", COMBO_DYN_TEXT); println!("{}", BOLD_TEXT); println!("{}", DIM_TEXT); println!("{}", ITALIC_TEXT); println!("{}", UNDERLINE_TEXT); println!("{}", BLINK_TEXT); println!("{}", BLINK_FAST_TEXT); println!("{}", REVERSED_TEXT); println!("{}", HIDDEN_TEXT); println!("{}", STRIKETHROUGH_TEXT); println!("{}", STYLED_TEXT); println!("{}", STYLED_TEXT_2); } owo-colors-4.2.3/examples/custom_colors.rs000064400000000000000000000003241046102023000170130ustar 00000000000000use owo_colors::OwoColorize; use owo_colors::colors::CustomColor; fn main() { println!("{}", "custom purple".fg::>()); println!("{}", "custom green".fg_rgb::<50, 209, 42>()); } owo-colors-4.2.3/examples/dyn_colors.rs000064400000000000000000000013321046102023000162730ustar 00000000000000use owo_colors::{AnsiColors, DynColors, OwoColorize, Rgb, XtermColors}; fn random_number() -> u32 { 2 } fn main() { let mut color = AnsiColors::Red; println!("{}", "red".color(color)); color = AnsiColors::Blue; println!("{}", "blue".color(color)); let color = XtermColors::Fuchsia; println!("{}", "fuchsia".color(color)); let color = Rgb(141, 59, 212); println!("{}", "custom purple".color(color)); let color = match random_number() { 1 => DynColors::Rgb(141, 59, 212), 2 => DynColors::Ansi(AnsiColors::BrightGreen), 3 => "#F3F3F3".parse().unwrap(), _ => DynColors::Xterm(XtermColors::Aqua), }; println!("{}", "mystery color".color(color)); } owo-colors-4.2.3/examples/extra_colors.rs000064400000000000000000000007421046102023000166300ustar 00000000000000use owo_colors::{OwoColorize, colors::xterm}; fn main() { println!("{}", "Electric violet".fg::()); println!("{}", "Matrix".fg::()); println!("{}", "Flirt".fg::()); println!("{}", "Cyan2".fg::()); println!("{}", "Cyan".fg::()); println!("{}", "Lime".fg::()); println!("{}", "Jade".fg::()); println!("{}", "Reef".fg::()); } owo-colors-4.2.3/examples/override.rs000064400000000000000000000010361046102023000157400ustar 00000000000000use owo_colors::{OwoColorize, Stream::Stdout}; fn main() { println!("Override color=always"); owo_colors::set_override(true); println!("{}", "blue".if_supports_color(Stdout, |text| text.blue())); println!("Override color=never"); owo_colors::set_override(false); println!("{}", "green".if_supports_color(Stdout, |text| text.green())); println!("Override color=auto"); owo_colors::unset_override(); println!( "{}", "yellow".if_supports_color(Stdout, |text| text.bright_yellow()) ); } owo-colors-4.2.3/examples/supports_color.rs000064400000000000000000000003311046102023000172130ustar 00000000000000use owo_colors::{OwoColorize, Stream::Stdout}; fn main() { println!( "{}", "This will be red if viewed through a compatible terminal!" .if_supports_color(Stdout, |x| x.red()) ); } owo-colors-4.2.3/release.toml000064400000000000000000000003551046102023000142550ustar 00000000000000sign-tag = true consolidate-commits = false pre-release-commit-message = "[{{crate_name}}] version {{version}}" tag-message = "[{{crate_name}}] version {{version}}" tag-name = "v{{version}}" publish = false dependent-version = "upgrade" owo-colors-4.2.3/rustfmt.toml000064400000000000000000000000501046102023000143310ustar 00000000000000edition = "2021" style_edition = "2024" owo-colors-4.2.3/scripts/cargo-release-publish.sh000075500000000000000000000007361046102023000201460ustar 00000000000000#!/bin/bash # Use cargo-release to publish crates to crates.io. set -xe -o pipefail # cargo-release requires a release off a branch (maybe it shouldn't?) # Check out this branch, creating it if it doesn't exist. git checkout -B to-release # --execute: actually does the release # --no-confirm: don't ask for confirmation, since this is a non-interactive script cargo release publish --publish --execute --no-confirm --workspace "$@" git checkout - git branch -D to-release owo-colors-4.2.3/src/colors/css.rs000064400000000000000000000151151046102023000151660ustar 00000000000000macro_rules! css_color_types { ($( $name:ident ($r:literal, $g:literal, $b:literal) )*) => { use crate::{Color, colors::CustomColor}; use core::fmt; pub(crate) mod dynamic { #[cfg(doc)] use crate::OwoColorize; /// Available CSS colors for use with [`OwoColorize::color`](OwoColorize::color) /// or [`OwoColorize::on_color`](OwoColorize::on_color) #[allow(missing_docs)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CssColors { $($name,)* } } use dynamic::CssColors; impl crate::private::Sealed for CssColors {} impl crate::DynColor for CssColors { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( CssColors::$name => CustomColor::<$r, $g, $b>::ANSI_FG, )* }; f.write_str(color) } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( CssColors::$name => CustomColor::<$r, $g, $b>::ANSI_BG, )* }; f.write_str(color) } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( CssColors::$name => CustomColor::<$r, $g, $b>::RAW_ANSI_FG, )* }; f.write_str(color) } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( CssColors::$name => CustomColor::<$r, $g, $b>::RAW_ANSI_BG, )* }; f.write_str(color) } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { crate::DynColors::Css(*self) } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { crate::DynColors::Css(*self) } } $( #[allow(missing_docs)] pub type $name = CustomColor<$r, $g, $b>; )* }; } css_color_types! { AliceBlue (240, 248, 255) AntiqueWhite (250, 235, 215) Aqua (0, 255, 255) Aquamarine (127, 255, 212) Azure (240, 255, 255) Beige (245, 245, 220) Bisque (255, 228, 196) Black (0, 0, 0) BlanchedAlmond (255, 235, 205) Blue (0, 0, 255) BlueViolet (138, 43, 226) Brown (165, 42, 42) BurlyWood (222, 184, 135) CadetBlue (95, 158, 160) Chartreuse (127, 255, 0) Chocolate (210, 105, 30) Coral (255, 127, 80) CornflowerBlue (100, 149, 237) Cornsilk (255, 248, 220) Crimson (220, 20, 60) DarkBlue (0, 0, 139) DarkCyan (0, 139, 139) DarkGoldenRod (184, 134, 11) DarkGray (169, 169, 169) DarkGrey (169, 169, 169) DarkGreen (0, 100, 0) DarkKhaki (189, 183, 107) DarkMagenta (139, 0, 139) DarkOliveGreen (85, 107, 47) DarkOrange (255, 140, 0) DarkOrchid (153, 50, 204) DarkRed (139, 0, 0) DarkSalmon (233, 150, 122) DarkSeaGreen (143, 188, 143) DarkSlateBlue (72, 61, 139) DarkSlateGray (47, 79, 79) DarkSlateGrey (47, 79, 79) DarkTurquoise (0, 206, 209) DarkViolet (148, 0, 211) DeepPink (255, 20, 147) DeepSkyBlue (0, 191, 255) DimGray (105, 105, 105) DimGrey (105, 105, 105) DodgerBlue (30, 144, 255) FireBrick (178, 34, 34) FloralWhite (255, 250, 240) ForestGreen (34, 139, 34) Fuchsia (255, 0, 255) Gainsboro (220, 220, 220) GhostWhite (248, 248, 255) Gold (255, 215, 0) GoldenRod (218, 165, 32) Gray (128, 128, 128) Grey (128, 128, 128) Green (0, 128, 0) GreenYellow (173, 255, 47) HoneyDew (240, 255, 240) HotPink (255, 105, 180) IndianRed (205, 92, 92) Indigo (75, 0, 130) Ivory (255, 255, 240) Khaki (240, 230, 140) Lavender (230, 230, 250) LavenderBlush (255, 240, 245) LawnGreen (124, 252, 0) LemonChiffon (255, 250, 205) LightBlue (173, 216, 230) LightCoral (240, 128, 128) LightCyan (224, 255, 255) LightGoldenRodYellow (250, 250, 210) LightGray (211, 211, 211) LightGrey (211, 211, 211) LightGreen (144, 238, 144) LightPink (255, 182, 193) LightSalmon (255, 160, 122) LightSeaGreen (32, 178, 170) LightSkyBlue (135, 206, 250) LightSlateGray (119, 136, 153) LightSlateGrey (119, 136, 153) LightSteelBlue (176, 196, 222) LightYellow (255, 255, 224) Lime (0, 255, 0) LimeGreen (50, 205, 50) Linen (250, 240, 230) Magenta (255, 0, 255) Maroon (128, 0, 0) MediumAquaMarine (102, 205, 170) MediumBlue (0, 0, 205) MediumOrchid (186, 85, 211) MediumPurple (147, 112, 219) MediumSeaGreen (60, 179, 113) MediumSlateBlue (123, 104, 238) MediumSpringGreen (0, 250, 154) MediumTurquoise (72, 209, 204) MediumVioletRed (199, 21, 133) MidnightBlue (25, 25, 112) MintCream (245, 255, 250) MistyRose (255, 228, 225) Moccasin (255, 228, 181) NavajoWhite (255, 222, 173) Navy (0, 0, 128) OldLace (253, 245, 230) Olive (128, 128, 0) OliveDrab (107, 142, 35) Orange (255, 165, 0) OrangeRed (255, 69, 0) Orchid (218, 112, 214) PaleGoldenRod (238, 232, 170) PaleGreen (152, 251, 152) PaleTurquoise (175, 238, 238) PaleVioletRed (219, 112, 147) PapayaWhip (255, 239, 213) PeachPuff (255, 218, 185) Peru (205, 133, 63) Pink (255, 192, 203) Plum (221, 160, 221) PowderBlue (176, 224, 230) Purple (128, 0, 128) RebeccaPurple (102, 51, 153) Red (255, 0, 0) RosyBrown (188, 143, 143) RoyalBlue (65, 105, 225) SaddleBrown (139, 69, 19) Salmon (250, 128, 114) SandyBrown (244, 164, 96) SeaGreen (46, 139, 87) SeaShell (255, 245, 238) Sienna (160, 82, 45) Silver (192, 192, 192) SkyBlue (135, 206, 235) SlateBlue (106, 90, 205) SlateGray (112, 128, 144) SlateGrey (112, 128, 144) Snow (255, 250, 250) SpringGreen (0, 255, 127) SteelBlue (70, 130, 180) Tan (210, 180, 140) Teal (0, 128, 128) Thistle (216, 191, 216) Tomato (255, 99, 71) Turquoise (64, 224, 208) Violet (238, 130, 238) Wheat (245, 222, 179) White (255, 255, 255) WhiteSmoke (245, 245, 245) Yellow (255, 255, 0) YellowGreen (154, 205, 50) } owo-colors-4.2.3/src/colors/custom.rs000064400000000000000000000056031046102023000157110ustar 00000000000000use crate::Color; const U8_TO_STR: [[u8; 3]; 256] = generate_lookup(); const fn generate_lookup() -> [[u8; 3]; 256] { let mut table = [[0, 0, 0]; 256]; let mut i = 0; while i < 256 { table[i] = [ b'0' + (i / 100) as u8, b'0' + (i / 10 % 10) as u8, b'0' + (i % 10) as u8, ]; i += 1; } table } enum Plane { Fg, Bg, } const fn rgb_to_ansi(r: u8, g: u8, b: u8, plane: Plane) -> [u8; 19] { let mut buf = match plane { Plane::Fg => *b"\x1b[38;2;rrr;ggg;bbbm", Plane::Bg => *b"\x1b[48;2;rrr;ggg;bbbm", }; let r = U8_TO_STR[r as usize]; let g = U8_TO_STR[g as usize]; let b = U8_TO_STR[b as usize]; // r 7 buf[7] = r[0]; buf[8] = r[1]; buf[9] = r[2]; // g 11 buf[11] = g[0]; buf[12] = g[1]; buf[13] = g[2]; // b 15 buf[15] = b[0]; buf[16] = b[1]; buf[17] = b[2]; buf } const fn rgb_to_ansi_color(r: u8, g: u8, b: u8, plane: Plane) -> [u8; 16] { let mut buf = match plane { Plane::Fg => *b"38;2;rrr;ggg;bbb", Plane::Bg => *b"48;2;rrr;ggg;bbb", }; let r = U8_TO_STR[r as usize]; let g = U8_TO_STR[g as usize]; let b = U8_TO_STR[b as usize]; // r 5 buf[5] = r[0]; buf[6] = r[1]; buf[7] = r[2]; // g 9 buf[9] = g[0]; buf[10] = g[1]; buf[11] = g[2]; // b 13 buf[13] = b[0]; buf[14] = b[1]; buf[15] = b[2]; buf } /// A custom RGB color, determined at compile time pub struct CustomColor; /// This exists since unwrap() isn't const-safe (it invokes formatting infrastructure) const fn bytes_to_str(bytes: &'static [u8]) -> &'static str { match core::str::from_utf8(bytes) { Ok(o) => o, Err(_e) => panic!("Const parsing &[u8] to a string failed!"), } } impl CustomColor { const ANSI_FG_U8: [u8; 19] = rgb_to_ansi(R, G, B, Plane::Fg); const ANSI_BG_U8: [u8; 19] = rgb_to_ansi(R, G, B, Plane::Bg); const RAW_ANSI_FG_U8: [u8; 16] = rgb_to_ansi_color(R, G, B, Plane::Fg); const RAW_ANSI_BG_U8: [u8; 16] = rgb_to_ansi_color(R, G, B, Plane::Bg); } impl crate::private::Sealed for CustomColor {} impl Color for CustomColor { const ANSI_FG: &'static str = bytes_to_str(&Self::ANSI_FG_U8); const ANSI_BG: &'static str = bytes_to_str(&Self::ANSI_BG_U8); const RAW_ANSI_FG: &'static str = bytes_to_str(&Self::RAW_ANSI_FG_U8); const RAW_ANSI_BG: &'static str = bytes_to_str(&Self::RAW_ANSI_BG_U8); #[doc(hidden)] type DynEquivalent = crate::Rgb; #[doc(hidden)] const DYN_EQUIVALENT: Self::DynEquivalent = crate::Rgb(R, G, B); #[doc(hidden)] const DYN_COLORS_EQUIVALENT: crate::DynColors = crate::DynColors::Rgb(R, G, B); } owo-colors-4.2.3/src/colors/dynamic.rs000064400000000000000000000063131046102023000160220ustar 00000000000000use crate::{AnsiColors, DynColor}; use core::fmt; #[allow(unused_imports)] use crate::OwoColorize; /// Available RGB colors for use with [`OwoColorize::color`](OwoColorize::color) /// or [`OwoColorize::on_color`](OwoColorize::on_color) #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Rgb(pub u8, pub u8, pub u8); impl crate::private::Sealed for Rgb {} impl DynColor for Rgb { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Rgb(r, g, b) = self; write!(f, "\x1b[38;2;{r};{g};{b}m") } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Rgb(r, g, b) = self; write!(f, "\x1b[48;2;{r};{g};{b}m") } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Rgb(r, g, b) = self; write!(f, "38;2;{r};{g};{b}") } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Rgb(r, g, b) = self; write!(f, "48;2;{r};{g};{b}") } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { let Rgb(r, g, b) = self; crate::DynColors::Rgb(*r, *g, *b) } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { self.get_dyncolors_fg() } } impl crate::private::Sealed for str {} impl DynColor for str { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color: AnsiColors = self.into(); color.fmt_ansi_fg(f) } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color: AnsiColors = self.into(); color.fmt_ansi_bg(f) } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color: AnsiColors = self.into(); color.fmt_raw_ansi_fg(f) } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color: AnsiColors = self.into(); color.fmt_raw_ansi_bg(f) } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { crate::DynColors::Ansi(self.into()) } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { crate::DynColors::Ansi(self.into()) } } /// Implemented for drop-in replacement support for `colored` impl<'a> From<&'a str> for AnsiColors { fn from(color: &'a str) -> Self { #[allow(clippy::match_same_arms)] // defaults to white color match color { "black" => AnsiColors::Black, "red" => AnsiColors::Red, "green" => AnsiColors::Green, "yellow" => AnsiColors::Yellow, "blue" => AnsiColors::Blue, "magenta" | "purple" => AnsiColors::Magenta, "cyan" => AnsiColors::Cyan, "white" => AnsiColors::White, "bright black" => AnsiColors::BrightBlack, "bright red" => AnsiColors::BrightRed, "bright green" => AnsiColors::BrightGreen, "bright yellow" => AnsiColors::BrightYellow, "bright blue" => AnsiColors::BrightBlue, "bright magenta" => AnsiColors::BrightMagenta, "bright cyan" => AnsiColors::BrightCyan, "bright white" => AnsiColors::BrightWhite, _ => AnsiColors::White, } } } owo-colors-4.2.3/src/colors/xterm.rs000064400000000000000000000345761046102023000155510ustar 00000000000000macro_rules! xterm_colors { ($( $xterm_num:literal $name:ident ($r:literal, $g:literal, $b:literal) )*) => { pub(crate) mod dynamic { use core::fmt; #[allow(unused_imports)] use crate::OwoColorize; /// Available Xterm colors for use with [`OwoColorize::color`](OwoColorize::color) /// or [`OwoColorize::on_color`](OwoColorize::on_color) #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum XtermColors { $( #[allow(missing_docs)] $name, )* } impl crate::private::Sealed for XtermColors {} impl crate::DynColor for XtermColors { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( XtermColors::$name => concat!("\x1b[38;5;", stringify!($xterm_num), "m"), )* }; f.write_str(color) } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( XtermColors::$name => concat!("\x1b[48;5;", stringify!($xterm_num), "m"), )* }; f.write_str(color) } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( XtermColors::$name => concat!("38;5;", stringify!($xterm_num)), )* }; f.write_str(color) } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( XtermColors::$name => concat!("48;5;", stringify!($xterm_num)), )* }; f.write_str(color) } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { crate::DynColors::Xterm(*self) } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { crate::DynColors::Xterm(*self) } } impl From for XtermColors { fn from(x: u8) -> Self { match x { $( $xterm_num => XtermColors::$name, )* } } } impl From for u8 { fn from(color: XtermColors) -> Self { match color { $( XtermColors::$name => $xterm_num, )* } } } } $( #[allow(missing_docs)] pub struct $name; impl crate::private::Sealed for $name {} impl crate::Color for $name { const ANSI_FG: &'static str = concat!("\x1b[38;5;", stringify!($xterm_num), "m"); const ANSI_BG: &'static str = concat!("\x1b[48;5;", stringify!($xterm_num), "m"); const RAW_ANSI_BG: &'static str = concat!("48;5;", stringify!($xterm_num)); const RAW_ANSI_FG: &'static str = concat!("38;5;", stringify!($xterm_num)); #[doc(hidden)] type DynEquivalent = dynamic::XtermColors; #[doc(hidden)] const DYN_EQUIVALENT: Self::DynEquivalent = dynamic::XtermColors::$name; #[doc(hidden)] const DYN_COLORS_EQUIVALENT: crate::DynColors = crate::DynColors::Xterm(Self::DYN_EQUIVALENT); } )* }; } xterm_colors! { 0 UserBlack (0,0,0) 1 UserRed (128,0,0) 2 UserGreen (0,128,0) 3 UserYellow (128,128,0) 4 UserBlue (0,0,128) 5 UserMagenta (128,0,128) 6 UserCyan (0,128,128) 7 UserWhite (192,192,192) 8 UserBrightBlack (128,128,128) 9 UserBrightRed (255,0,0) 10 UserBrightGreen (0,255,0) 11 UserBrightYellow (255,255,0) 12 UserBrightBlue (0,0,255) 13 UserBrightMagenta (255,0,255) 14 UserBrightCyan (0,255,255) 15 UserBrightWhite (255,255,255) 16 Black (0,0,0) 17 StratosBlue (0,0,95) 18 NavyBlue (0,0,135) 19 MidnightBlue (0,0,175) 20 DarkBlue (0,0,215) 21 Blue (0,0,255) 22 CamaroneGreen (0,95,0) 23 BlueStone (0,95,95) 24 OrientBlue (0,95,135) 25 EndeavourBlue (0,95,175) 26 ScienceBlue (0,95,215) 27 BlueRibbon (0,95,255) 28 JapaneseLaurel (0,135,0) 29 DeepSeaGreen (0,135,95) 30 Teal (0,135,135) 31 DeepCerulean (0,135,175) 32 LochmaraBlue (0,135,215) 33 AzureRadiance (0,135,255) 34 LightJapaneseLaurel (0,175,0) 35 Jade (0,175,95) 36 PersianGreen (0,175,135) 37 BondiBlue (0,175,175) 38 Cerulean (0,175,215) 39 LightAzureRadiance (0,175,255) 40 DarkGreen (0,215,0) 41 Malachite (0,215,95) 42 CaribbeanGreen (0,215,135) 43 LightCaribbeanGreen (0,215,175) 44 RobinEggBlue (0,215,215) 45 Aqua (0,215,255) 46 Green (0,255,0) 47 DarkSpringGreen (0,255,95) 48 SpringGreen (0,255,135) 49 LightSpringGreen (0,255,175) 50 BrightTurquoise (0,255,215) 51 Cyan (0,255,255) 52 Rosewood (95,0,0) 53 PompadourMagenta (95,0,95) 54 PigmentIndigo (95,0,135) 55 DarkPurple (95,0,175) 56 ElectricIndigo (95,0,215) 57 ElectricPurple (95,0,255) 58 VerdunGreen (95,95,0) 59 ScorpionOlive (95,95,95) 60 Lilac (95,95,135) 61 ScampiIndigo (95,95,175) 62 Indigo (95,95,215) 63 DarkCornflowerBlue (95,95,255) 64 DarkLimeade (95,135,0) 65 GladeGreen (95,135,95) 66 JuniperGreen (95,135,135) 67 HippieBlue (95,135,175) 68 HavelockBlue (95,135,215) 69 CornflowerBlue (95,135,255) 70 Limeade (95,175,0) 71 FernGreen (95,175,95) 72 SilverTree (95,175,135) 73 Tradewind (95,175,175) 74 ShakespeareBlue (95,175,215) 75 DarkMalibuBlue (95,175,255) 76 DarkBrightGreen (95,215,0) 77 DarkPastelGreen (95,215,95) 78 PastelGreen (95,215,135) 79 DownyTeal (95,215,175) 80 Viking (95,215,215) 81 MalibuBlue (95,215,255) 82 BrightGreen (95,255,0) 83 DarkScreaminGreen (95,255,95) 84 ScreaminGreen (95,255,135) 85 DarkAquamarine (95,255,175) 86 Aquamarine (95,255,215) 87 LightAquamarine (95,255,255) 88 Maroon (135,0,0) 89 DarkFreshEggplant (135,0,95) 90 LightFreshEggplant (135,0,135) 91 Purple (135,0,175) 92 ElectricViolet (135,0,215) 93 LightElectricViolet (135,0,255) 94 Brown (135,95,0) 95 CopperRose (135,95,95) 96 StrikemasterPurple (135,95,135) 97 DelugePurple (135,95,175) 98 DarkMediumPurple (135,95,215) 99 DarkHeliotropePurple (135,95,255) 100 Olive (135,135,0) 101 ClayCreekOlive (135,135,95) 102 DarkGray (135,135,135) 103 WildBlueYonder (135,135,175) 104 ChetwodeBlue (135,135,215) 105 SlateBlue (135,135,255) 106 LightLimeade (135,175,0) 107 ChelseaCucumber (135,175,95) 108 BayLeaf (135,175,135) 109 GulfStream (135,175,175) 110 PoloBlue (135,175,215) 111 LightMalibuBlue (135,175,255) 112 Pistachio (135,215,0) 113 LightPastelGreen (135,215,95) 114 DarkFeijoaGreen (135,215,135) 115 VistaBlue (135,215,175) 116 Bermuda (135,215,215) 117 DarkAnakiwaBlue (135,215,255) 118 ChartreuseGreen (135,255,0) 119 LightScreaminGreen (135,255,95) 120 DarkMintGreen (135,255,135) 121 MintGreen (135,255,175) 122 LighterAquamarine (135,255,215) 123 AnakiwaBlue (135,255,255) 124 BrightRed (175,0,0) 125 DarkFlirt (175,0,95) 126 Flirt (175,0,135) 127 LightFlirt (175,0,175) 128 DarkViolet (175,0,215) 129 BrightElectricViolet (175,0,255) 130 RoseofSharonOrange (175,95,0) 131 MatrixPink (175,95,95) 132 TapestryPink (175,95,135) 133 FuchsiaPink (175,95,175) 134 MediumPurple (175,95,215) 135 Heliotrope (175,95,255) 136 PirateGold (175,135,0) 137 MuesliOrange (175,135,95) 138 PharlapPink (175,135,135) 139 Bouquet (175,135,175) 140 Lavender (175,135,215) 141 LightHeliotrope (175,135,255) 142 BuddhaGold (175,175,0) 143 OliveGreen (175,175,95) 144 HillaryOlive (175,175,135) 145 SilverChalice (175,175,175) 146 WistfulLilac (175,175,215) 147 MelroseLilac (175,175,255) 148 RioGrandeGreen (175,215,0) 149 ConiferGreen (175,215,95) 150 Feijoa (175,215,135) 151 PixieGreen (175,215,175) 152 JungleMist (175,215,215) 153 LightAnakiwaBlue (175,215,255) 154 Lime (175,255,0) 155 GreenYellow (175,255,95) 156 LightMintGreen (175,255,135) 157 Celadon (175,255,175) 158 AeroBlue (175,255,215) 159 FrenchPassLightBlue (175,255,255) 160 GuardsmanRed (215,0,0) 161 RazzmatazzCerise (215,0,95) 162 MediumVioletRed (215,0,135) 163 HollywoodCerise (215,0,175) 164 DarkPurplePizzazz (215,0,215) 165 BrighterElectricViolet (215,0,255) 166 TennOrange (215,95,0) 167 RomanOrange (215,95,95) 168 CranberryPink (215,95,135) 169 HopbushPink (215,95,175) 170 Orchid (215,95,215) 171 LighterHeliotrope (215,95,255) 172 MangoTango (215,135,0) 173 Copperfield (215,135,95) 174 SeaPink (215,135,135) 175 CanCanPink (215,135,175) 176 LightOrchid (215,135,215) 177 BrightHeliotrope (215,135,255) 178 DarkCorn (215,175,0) 179 DarkTachaOrange (215,175,95) 180 TanBeige (215,175,135) 181 ClamShell (215,175,175) 182 ThistlePink (215,175,215) 183 Mauve (215,175,255) 184 Corn (215,215,0) 185 TachaOrange (215,215,95) 186 DecoOrange (215,215,135) 187 PaleGoldenrod (215,215,175) 188 AltoBeige (215,215,215) 189 FogPink (215,215,255) 190 ChartreuseYellow (215,255,0) 191 Canary (215,255,95) 192 Honeysuckle (215,255,135) 193 ReefPaleYellow (215,255,175) 194 SnowyMint (215,255,215) 195 OysterBay (215,255,255) 196 Red (255,0,0) 197 DarkRose (255,0,95) 198 Rose (255,0,135) 199 LightHollywoodCerise (255,0,175) 200 PurplePizzazz (255,0,215) 201 Fuchsia (255,0,255) 202 BlazeOrange (255,95,0) 203 BittersweetOrange (255,95,95) 204 WildWatermelon (255,95,135) 205 DarkHotPink (255,95,175) 206 HotPink (255,95,215) 207 PinkFlamingo (255,95,255) 208 FlushOrange (255,135,0) 209 Salmon (255,135,95) 210 VividTangerine (255,135,135) 211 PinkSalmon (255,135,175) 212 DarkLavenderRose (255,135,215) 213 BlushPink (255,135,255) 214 YellowSea (255,175,0) 215 TexasRose (255,175,95) 216 Tacao (255,175,135) 217 Sundown (255,175,175) 218 CottonCandy (255,175,215) 219 LavenderRose (255,175,255) 220 Gold (255,215,0) 221 Dandelion (255,215,95) 222 GrandisCaramel (255,215,135) 223 Caramel (255,215,175) 224 CosmosSalmon (255,215,215) 225 PinkLace (255,215,255) 226 Yellow (255,255,0) 227 LaserLemon (255,255,95) 228 DollyYellow (255,255,135) 229 PortafinoYellow (255,255,175) 230 Cumulus (255,255,215) 231 White (255,255,255) 232 DarkCodGray (8,8,8) 233 CodGray (18,18,18) 234 LightCodGray (28,28,28) 235 DarkMineShaft (38,38,38) 236 MineShaft (48,48,48) 237 LightMineShaft (58,58,58) 238 DarkTundora (68,68,68) 239 Tundora (78,78,78) 240 ScorpionGray (88,88,88) 241 DarkDoveGray (98,98,98) 242 DoveGray (108,108,108) 243 Boulder (118,118,118) 244 Gray (128,128,128) 245 LightGray (138,138,138) 246 DustyGray (148,148,148) 247 NobelGray (158,158,158) 248 DarkSilverChalice (168,168,168) 249 LightSilverChalice (178,178,178) 250 DarkSilver (188,188,188) 251 Silver (198,198,198) 252 DarkAlto (208,208,208) 253 Alto (218,218,218) 254 Mercury (228,228,228) 255 GalleryGray (238,238,238) } owo-colors-4.2.3/src/colors.rs000064400000000000000000000146121046102023000143770ustar 00000000000000//! Color types for used for being generic over the color use crate::{BgColorDisplay, BgDynColorDisplay, FgColorDisplay, FgDynColorDisplay}; use core::fmt; macro_rules! colors { ($( $color:ident $fg:literal $bg:literal ),* $(,)?) => { pub(crate) mod ansi_colors { use core::fmt; #[allow(unused_imports)] use crate::OwoColorize; /// Available standard ANSI colors for use with [`OwoColorize::color`](OwoColorize::color) /// or [`OwoColorize::on_color`](OwoColorize::on_color) #[allow(missing_docs)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum AnsiColors { $( $color, )* } impl crate::private::Sealed for AnsiColors {} impl crate::DynColor for AnsiColors { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( AnsiColors::$color => concat!("\x1b[", stringify!($fg), "m"), )* }; write!(f, "{}", color) } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( AnsiColors::$color => concat!("\x1b[", stringify!($bg), "m"), )* }; write!(f, "{}", color) } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( AnsiColors::$color => stringify!($fg), )* }; f.write_str(color) } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let color = match self { $( AnsiColors::$color => stringify!($bg), )* }; f.write_str(color) } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { crate::DynColors::Ansi(*self) } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { crate::DynColors::Ansi(*self) } } } $( /// A color for use with [`OwoColorize`](crate::OwoColorize)'s `fg` and `bg` methods. pub struct $color; impl crate::private::Sealed for $color {} impl crate::Color for $color { const ANSI_FG: &'static str = concat!("\x1b[", stringify!($fg), "m"); const ANSI_BG: &'static str = concat!("\x1b[", stringify!($bg), "m"); const RAW_ANSI_FG: &'static str = stringify!($fg); const RAW_ANSI_BG: &'static str = stringify!($bg); #[doc(hidden)] type DynEquivalent = ansi_colors::AnsiColors; #[doc(hidden)] const DYN_EQUIVALENT: Self::DynEquivalent = ansi_colors::AnsiColors::$color; #[doc(hidden)] const DYN_COLORS_EQUIVALENT: crate::DynColors = crate::DynColors::Ansi(ansi_colors::AnsiColors::$color); } )* }; } colors! { Black 30 40, Red 31 41, Green 32 42, Yellow 33 43, Blue 34 44, Magenta 35 45, Cyan 36 46, White 37 47, Default 39 49, BrightBlack 90 100, BrightRed 91 101, BrightGreen 92 102, BrightYellow 93 103, BrightBlue 94 104, BrightMagenta 95 105, BrightCyan 96 106, BrightWhite 97 107, } macro_rules! impl_fmt_for { ($($trait:path),* $(,)?) => { $( impl<'a, Color: crate::Color, T: ?Sized + $trait> $trait for FgColorDisplay<'a, Color, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(Color::ANSI_FG)?; ::fmt(&self.0, f)?; f.write_str("\x1b[39m") } } impl<'a, Color: crate::Color, T: ?Sized + $trait> $trait for BgColorDisplay<'a, Color, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(Color::ANSI_BG)?; ::fmt(&self.0, f)?; f.write_str("\x1b[49m") } } )* }; } impl_fmt_for! { fmt::Display, fmt::Debug, fmt::UpperHex, fmt::LowerHex, fmt::Binary, fmt::UpperExp, fmt::LowerExp, fmt::Octal, fmt::Pointer, } macro_rules! impl_fmt_for_dyn { ($($trait:path),* $(,)?) => { $( impl<'a, Color: crate::DynColor, T: ?Sized + $trait> $trait for FgDynColorDisplay<'a, Color, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { (self.1).fmt_ansi_fg(f)?; ::fmt(&self.0, f)?; f.write_str("\x1b[39m") } } impl<'a, Color: crate::DynColor, T: ?Sized + $trait> $trait for BgDynColorDisplay<'a, Color, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { (self.1).fmt_ansi_bg(f)?; ::fmt(&self.0, f)?; f.write_str("\x1b[49m") } } )* }; } impl_fmt_for_dyn! { fmt::Display, fmt::Debug, fmt::UpperHex, fmt::LowerHex, fmt::Binary, fmt::UpperExp, fmt::LowerExp, fmt::Octal, fmt::Pointer, } /// CSS named colors. Not as widely supported as standard ANSI as it relies on 48bit color support. /// /// Reference: /// Reference: pub mod css; /// XTerm 256-bit colors. Not as widely supported as standard ANSI but contains 240 more colors. pub mod xterm; mod custom; pub use custom::CustomColor; pub(crate) mod dynamic; owo-colors-4.2.3/src/combo.rs000064400000000000000000001027051046102023000141760ustar 00000000000000use crate::{BgColorDisplay, Color, FgColorDisplay}; use crate::{BgDynColorDisplay, DynColor, FgDynColorDisplay, Style, Styled, colors}; use core::fmt; use core::marker::PhantomData; #[cfg(doc)] use crate::OwoColorize; /// A wrapper type which applies both a foreground and background color pub struct ComboColorDisplay<'a, Fg: Color, Bg: Color, T: ?Sized>(&'a T, PhantomData<(Fg, Bg)>); /// Wrapper around a type which implements all the formatters the wrapped type does, with the /// addition of changing the foreground and background color. /// /// If compile-time coloring is an option, consider using [`ComboColorDisplay`] instead. pub struct ComboDynColorDisplay<'a, Fg: DynColor, Bg: DynColor, T: ?Sized>(&'a T, Fg, Bg); macro_rules! impl_fmt_for_combo { ($($trait:path),* $(,)?) => { $( impl<'a, Fg: Color, Bg: Color, T: ?Sized + $trait> $trait for ComboColorDisplay<'a, Fg, Bg, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("\x1b[")?; f.write_str(Fg::RAW_ANSI_FG)?; f.write_str(";")?; f.write_str(Bg::RAW_ANSI_BG)?; f.write_str("m")?; ::fmt(&self.0, f)?; f.write_str("\x1b[0m") } } )* $( impl<'a, Fg: DynColor, Bg: DynColor, T: ?Sized + $trait> $trait for ComboDynColorDisplay<'a, Fg, Bg, T> { #[inline(always)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("\x1b[")?; self.1.fmt_raw_ansi_fg(f)?; f.write_str(";")?; self.2.fmt_raw_ansi_bg(f)?; f.write_str("m")?; ::fmt(&self.0, f)?; f.write_str("\x1b[0m") } } )* }; } impl_fmt_for_combo! { fmt::Display, fmt::Debug, fmt::UpperHex, fmt::LowerHex, fmt::Binary, fmt::UpperExp, fmt::LowerExp, fmt::Octal, fmt::Pointer, } /// implement specialized color methods for FgColorDisplay BgColorDisplay, ComboColorDisplay macro_rules! color_methods { ($( #[$fg_meta:meta] #[$bg_meta:meta] $color:ident $fg_method:ident $bg_method:ident ),* $(,)?) => { const _: () = (); // workaround for syntax highlighting bug impl<'a, Fg, T: ?Sized> FgColorDisplay<'a, Fg, T> where Fg: Color, { /// Create a new [`FgColorDisplay`], from a reference to a type which implements /// [`Color`]. /// /// This is a const function: in non-const contexts, [`OwoColorize::fg`] or one of the /// other methods on it may be more convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::Green, FgColorDisplay}; /// /// const GREEN_TEXT: FgColorDisplay = FgColorDisplay::new("green"); /// /// println!("{}", GREEN_TEXT); /// # assert_eq!(format!("{}", GREEN_TEXT), "\x1b[32mgreen\x1b[39m"); /// ``` pub const fn new(thing: &'a T) -> Self { Self(thing, PhantomData) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// Typical use: /// /// ```rust /// use owo_colors::OwoColorize; /// /// fn is_blue() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_blue() { /// "hello".blue().into_styled() /// } else { /// "hello".green().into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[34mhello\x1b[0m"); /// ``` /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::{Blue, Green}, FgColorDisplay, Styled}; /// /// const fn is_blue() -> bool { /// // ... /// # true /// } /// /// const STYLED_STR: Styled<&str> = if is_blue() { /// FgColorDisplay::::new("Hello").into_styled() /// } else { /// FgColorDisplay::::new("Hello").into_styled() /// }; /// /// println!("{}", STYLED_STR); /// # assert_eq!(format!("{}", STYLED_STR), "\x1b[34mHello\x1b[0m"); /// ``` pub const fn into_styled(self) -> Styled<&'a T> { let style = Style::new().fg::(); Styled { style, target: self.0 } } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color( self, fg: NewFg, ) -> FgDynColorDisplay<'a, NewFg, T> { FgDynColorDisplay(self.0, fg) } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color( self, bg: NewBg, ) -> ComboDynColorDisplay<'a, Fg::DynEquivalent, NewBg, T> { ComboDynColorDisplay(self.0, Fg::DYN_EQUIVALENT, bg) } /// Set the foreground color generically /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "red foreground".fg::()); /// ``` pub const fn fg(self) -> FgColorDisplay<'a, C, T> { FgColorDisplay(self.0, PhantomData) } /// Set the background color generically. /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "black background".bg::()); /// ``` pub const fn bg(self) -> ComboColorDisplay<'a, Fg, C, T> { ComboColorDisplay(self.0, PhantomData) } $( #[$fg_meta] #[inline(always)] pub const fn $fg_method(self) -> FgColorDisplay<'a, colors::$color, T> { FgColorDisplay(self.0, PhantomData) } #[$bg_meta] #[inline(always)] pub const fn $bg_method(self) -> ComboColorDisplay<'a, Fg, colors::$color, T> { ComboColorDisplay(self.0, PhantomData) } )* } const _: () = (); // workaround for syntax highlighting bug impl<'a, Bg, T: ?Sized> BgColorDisplay<'a, Bg, T> where Bg: Color, { /// Create a new [`BgColorDisplay`], from a reference to a type which implements /// [`Color`]. /// /// This is a const function: in non-const contexts, [`OwoColorize::bg`] may be more /// convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::Red, BgColorDisplay}; /// /// const RED_BG_TEXT: BgColorDisplay = BgColorDisplay::new("red background"); /// /// println!("{}", RED_BG_TEXT); /// # assert_eq!(format!("{}", RED_BG_TEXT), "\x1b[41mred background\x1b[49m"); /// ``` pub const fn new(thing: &'a T) -> Self { Self(thing, PhantomData) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// Typical use: /// /// ```rust /// use owo_colors::OwoColorize; /// /// fn is_red() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_red() { /// "hello".on_red().into_styled() /// } else { /// "hello".on_yellow().into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[41mhello\x1b[0m"); /// ``` /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::{Red, Yellow}, BgColorDisplay, Styled}; /// /// const fn is_red() -> bool { /// // ... /// # true /// } /// /// const STYLED_STR: Styled<&str> = if is_red() { /// BgColorDisplay::::new("Hello").into_styled() /// } else { /// BgColorDisplay::::new("Hello").into_styled() /// }; /// /// println!("{}", STYLED_STR); /// # assert_eq!(format!("{}", STYLED_STR), "\x1b[41mHello\x1b[0m"); /// ``` pub const fn into_styled(self) -> Styled<&'a T> { let style = Style::new().bg::(); Styled { style, target: self.0 } } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color( self, fg: NewFg, ) -> ComboDynColorDisplay<'a, NewFg, Bg::DynEquivalent, T> { ComboDynColorDisplay(self.0, fg, Bg::DYN_EQUIVALENT) } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color( self, bg: NewBg, ) -> BgDynColorDisplay<'a, NewBg, T> { BgDynColorDisplay(self.0, bg) } /// Set the foreground color generically /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "red foreground".fg::()); /// ``` pub const fn fg(self) -> ComboColorDisplay<'a, C, Bg, T> { ComboColorDisplay(self.0, PhantomData) } /// Set the background color generically. /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "black background".bg::()); /// ``` pub const fn bg(self) -> BgColorDisplay<'a, C, T> { BgColorDisplay(self.0, PhantomData) } $( #[$bg_meta] #[inline(always)] pub const fn $bg_method(self) -> BgColorDisplay<'a, colors::$color, T> { BgColorDisplay(self.0, PhantomData) } #[$fg_meta] #[inline(always)] pub const fn $fg_method(self) -> ComboColorDisplay<'a, colors::$color, Bg, T> { ComboColorDisplay(self.0, PhantomData) } )* } const _: () = (); // workaround for syntax highlighting bug impl<'a, Fg, Bg, T: ?Sized> ComboColorDisplay<'a, Fg, Bg, T> where Fg: Color, Bg: Color, { /// Create a new [`ComboColorDisplay`], from a pair of foreground and background types /// which implement [`Color`]. /// /// This is a const function: in non-const contexts, calling the [`OwoColorize`] /// functions may be more convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::{Blue, White}, ComboColorDisplay}; /// /// const COMBO_TEXT: ComboColorDisplay = /// ComboColorDisplay::new("blue text on white background"); /// /// println!("{}", COMBO_TEXT); /// # assert_eq!(format!("{}", COMBO_TEXT), "\x1b[34;47mblue text on white background\x1b[0m"); /// ``` pub const fn new(thing: &'a T) -> Self { Self(thing, PhantomData) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// Typical use: /// /// ```rust /// use owo_colors::OwoColorize; /// /// fn is_black_on_white() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_black_on_white() { /// "hello".black().on_white().into_styled() /// } else { /// "hello".white().on_black().into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[30;47mhello\x1b[0m"); /// ``` /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{colors::{Black, White}, ComboColorDisplay, Styled}; /// /// const fn is_black_on_white() -> bool { /// // ... /// # true /// } /// /// const STYLED_STR: Styled<&str> = if is_black_on_white() { /// ComboColorDisplay::::new("Hello").into_styled() /// } else { /// ComboColorDisplay::::new("Hello").into_styled() /// }; /// /// println!("{}", STYLED_STR); /// # assert_eq!(format!("{}", STYLED_STR), "\x1b[30;47mHello\x1b[0m"); /// ``` pub const fn into_styled(self) -> Styled<&'a T> { let style = Style::new().fg::().bg::(); Styled { style, target: self.0 } } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color( self, bg: NewBg, ) -> ComboDynColorDisplay<'a, Fg::DynEquivalent, NewBg, T> { ComboDynColorDisplay(self.0, Fg::DYN_EQUIVALENT, bg) } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color( self, fg: NewFg, ) -> ComboDynColorDisplay<'a, NewFg, Bg::DynEquivalent, T> { ComboDynColorDisplay(self.0, fg, Bg::DYN_EQUIVALENT) } /// Set the foreground color generically /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "red foreground".fg::()); /// ``` pub const fn fg(self) -> ComboColorDisplay<'a, C, Bg, T> { ComboColorDisplay(self.0, PhantomData) } /// Set the background color generically. /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "black background".bg::()); /// ``` pub const fn bg(self) -> ComboColorDisplay<'a, Fg, C, T> { ComboColorDisplay(self.0, PhantomData) } $( #[$bg_meta] #[inline(always)] pub const fn $bg_method(self) -> ComboColorDisplay<'a, Fg, colors::$color, T> { ComboColorDisplay(self.0, PhantomData) } #[$fg_meta] #[inline(always)] pub const fn $fg_method(self) -> ComboColorDisplay<'a, colors::$color, Bg, T> { ComboColorDisplay(self.0, PhantomData) } )* } }; } const _: () = (); // workaround for syntax highlighting bug color_methods! { /// Change the foreground color to black /// Change the background color to black Black black on_black, /// Change the foreground color to red /// Change the background color to red Red red on_red, /// Change the foreground color to green /// Change the background color to green Green green on_green, /// Change the foreground color to yellow /// Change the background color to yellow Yellow yellow on_yellow, /// Change the foreground color to blue /// Change the background color to blue Blue blue on_blue, /// Change the foreground color to magenta /// Change the background color to magenta Magenta magenta on_magenta, /// Change the foreground color to purple /// Change the background color to purple Magenta purple on_purple, /// Change the foreground color to cyan /// Change the background color to cyan Cyan cyan on_cyan, /// Change the foreground color to white /// Change the background color to white White white on_white, /// Change the foreground color to bright black /// Change the background color to bright black BrightBlack bright_black on_bright_black, /// Change the foreground color to bright red /// Change the background color to bright red BrightRed bright_red on_bright_red, /// Change the foreground color to bright green /// Change the background color to bright green BrightGreen bright_green on_bright_green, /// Change the foreground color to bright yellow /// Change the background color to bright yellow BrightYellow bright_yellow on_bright_yellow, /// Change the foreground color to bright blue /// Change the background color to bright blue BrightBlue bright_blue on_bright_blue, /// Change the foreground color to bright magenta /// Change the background color to bright magenta BrightMagenta bright_magenta on_bright_magenta, /// Change the foreground color to bright purple /// Change the background color to bright purple BrightMagenta bright_purple on_bright_purple, /// Change the foreground color to bright cyan /// Change the background color to bright cyan BrightCyan bright_cyan on_bright_cyan, /// Change the foreground color to bright white /// Change the background color to bright white BrightWhite bright_white on_bright_white, } impl<'a, Fg: DynColor + Copy, T: ?Sized> FgDynColorDisplay<'a, Fg, T> { /// Create a new [`FgDynColorDisplay`], from a reference to a type which implements /// [`DynColor`]. /// /// This is a const function: in non-const contexts, [`OwoColorize::color`] may be more /// convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{AnsiColors, FgDynColorDisplay}; /// /// const DYN_RED_TEXT: FgDynColorDisplay = /// FgDynColorDisplay::new("red text (dynamic)", AnsiColors::Red); /// /// println!("{}", DYN_RED_TEXT); /// # assert_eq!(format!("{}", DYN_RED_TEXT), "\x1b[31mred text (dynamic)\x1b[39m"); /// ``` pub const fn new(thing: &'a T, color: Fg) -> Self { Self(thing, color) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// ```rust /// use owo_colors::{AnsiColors, CssColors, OwoColorize}; /// /// fn is_blue() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_blue() { /// "hello".color(AnsiColors::Blue).into_styled() /// } else { /// "hello".color(CssColors::DarkSeaGreen).into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[34mhello\x1b[0m"); /// ``` pub fn into_styled(self) -> Styled<&'a T> { let Self(target, fg) = self; let style = Style::new().color(fg); Styled { style, target } } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color(self, bg: Bg) -> ComboDynColorDisplay<'a, Fg, Bg, T> { let Self(inner, fg) = self; ComboDynColorDisplay(inner, fg, bg) } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color(self, fg: NewFg) -> FgDynColorDisplay<'a, NewFg, T> { let Self(inner, _) = self; FgDynColorDisplay(inner, fg) } } impl<'a, Bg: DynColor + Copy, T: ?Sized> BgDynColorDisplay<'a, Bg, T> { /// Create a new [`BgDynColorDisplay`], from a reference to a type which implements /// [`DynColor`]. /// /// This is a const function: in non-const contexts, [`OwoColorize::on_color`] may be more /// convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{AnsiColors, BgDynColorDisplay}; /// /// const DYN_GREEN_BG_TEXT: BgDynColorDisplay = /// BgDynColorDisplay::new("green background (dynamic)", AnsiColors::Green); /// /// println!("{}", DYN_GREEN_BG_TEXT); /// # assert_eq!(format!("{}", DYN_GREEN_BG_TEXT), "\x1b[42mgreen background (dynamic)\x1b[49m"); /// ``` pub const fn new(thing: &'a T, color: Bg) -> Self { Self(thing, color) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// ```rust /// use owo_colors::{AnsiColors, CssColors, OwoColorize}; /// /// fn is_red() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_red() { /// "hello".on_color(AnsiColors::Red).into_styled() /// } else { /// "hello".on_color(CssColors::LightGoldenRodYellow).into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[41mhello\x1b[0m"); /// ``` pub fn into_styled(self) -> Styled<&'a T> { let Self(target, bg) = self; let style = Style::new().on_color(bg); Styled { style, target } } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color(self, bg: NewBg) -> BgDynColorDisplay<'a, NewBg, T> { let Self(inner, _) = self; BgDynColorDisplay(inner, bg) } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color(self, fg: Fg) -> ComboDynColorDisplay<'a, Fg, Bg, T> { let Self(inner, bg) = self; ComboDynColorDisplay(inner, fg, bg) } } impl<'a, Fg: DynColor + Copy, Bg: DynColor + Copy, T: ?Sized> ComboDynColorDisplay<'a, Fg, Bg, T> { /// Create a new [`ComboDynColorDisplay`], from a pair of types which implement /// [`DynColor`]. /// /// This is a const function: in non-const contexts, other functions may be more convenient. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{ComboDynColorDisplay, XtermColors}; /// /// const COMBO_DYN_TEXT: ComboDynColorDisplay = /// ComboDynColorDisplay::new( /// "blue text on lilac background (dynamic)", /// XtermColors::BlueRibbon, /// XtermColors::WistfulLilac, /// ); /// /// println!("{}", COMBO_DYN_TEXT); /// # assert_eq!(format!("{}", COMBO_DYN_TEXT), "\x1b[38;5;27;48;5;146mblue text on lilac background (dynamic)\x1b[0m"); /// ``` pub const fn new(thing: &'a T, fg: Fg, bg: Bg) -> Self { Self(thing, fg, bg) } /// Convert self to a generic [`Styled`]. /// /// This method erases color-related type parameters, and can be /// used to unify types across branches. /// /// # Example /// /// Typical use: /// /// ```rust /// use owo_colors::{AnsiColors, CssColors, OwoColorize}; /// /// fn is_black_on_white() -> bool { /// // ... /// # true /// } /// /// let styled_str = if is_black_on_white() { /// "hello".color(AnsiColors::Black).on_color(AnsiColors::White).into_styled() /// } else { /// "hello".color(CssColors::White).on_color(CssColors::Black).into_styled() /// }; /// /// println!("{}", styled_str); /// # assert_eq!(format!("{}", styled_str), "\x1b[30;47mhello\x1b[0m"); /// ``` pub fn into_styled(self) -> Styled<&'a T> { let Self(target, fg, bg) = self; let style = Style::new().color(fg).on_color(bg); Styled { style, target } } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`] or /// a color-specific method, such as [`OwoColorize::on_yellow`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` pub const fn on_color( self, bg: NewBg, ) -> ComboDynColorDisplay<'a, Fg, NewBg, T> { let Self(inner, fg, _) = self; ComboDynColorDisplay(inner, fg, bg) } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`] or /// a color-specific method, such as [`OwoColorize::green`], /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` pub const fn color(self, fg: NewFg) -> ComboDynColorDisplay<'a, NewFg, Bg, T> { // TODO: Make this const after https://github.com/rust-lang/rust/issues/73255 is stabilized. let Self(inner, _, bg) = self; ComboDynColorDisplay(inner, fg, bg) } } #[cfg(test)] mod tests { use crate::{AnsiColors, OwoColorize, colors::*}; #[test] fn fg_bg_combo() { let test = "test".red().on_blue(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn bg_fg_combo() { let test = "test".on_blue().red(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn fg_bg_dyn_combo() { let test = "test".color(AnsiColors::Red).on_color(AnsiColors::Blue); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn bg_fg_dyn_combo() { let test = "test".on_color(AnsiColors::Blue).color(AnsiColors::Red); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn fg_override() { let test = "test".green().yellow().red().on_blue(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn bg_override() { let test = "test".on_green().on_yellow().on_blue().red(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn multiple_override() { let test = "test" .on_green() .on_yellow() .on_red() .green() .on_blue() .red(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); let test = "test" .color(AnsiColors::Blue) .color(AnsiColors::White) .on_color(AnsiColors::Black) .color(AnsiColors::Red) .on_color(AnsiColors::Blue); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); let test = "test" .on_yellow() .on_red() .on_color(AnsiColors::Black) .color(AnsiColors::Red) .on_color(AnsiColors::Blue); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); let test = "test" .yellow() .red() .color(AnsiColors::Red) .on_color(AnsiColors::Black) .on_color(AnsiColors::Blue); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); let test = "test" .yellow() .red() .on_color(AnsiColors::Black) .color(AnsiColors::Red) .on_color(AnsiColors::Blue); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn generic_multiple_override() { use crate::colors::*; let test = "test" .bg::() .bg::() .bg::() .fg::() .bg::() .fg::(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn fg_bg_combo_generic() { let test = "test".fg::().bg::(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } #[test] fn bg_fg_combo_generic() { let test = "test".bg::().fg::(); assert_eq!(test.to_string(), "\x1b[31;44mtest\x1b[0m"); } } owo-colors-4.2.3/src/dyn_colors.rs000064400000000000000000000077741046102023000152640ustar 00000000000000#[allow(unused_imports)] use crate::{ AnsiColors, BgDynColorDisplay, CssColors, DynColor, FgDynColorDisplay, Rgb, XtermColors, }; use core::fmt; /// An enum describing runtime-configurable colors /// /// This can be displayed using [`FgDynColorDisplay`](FgDynColorDisplay) or [`BgDynColorDisplay`](BgDynColorDisplay), /// allowing for multiple types of colors to be used at runtime. #[allow(missing_docs)] #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum DynColors { Ansi(AnsiColors), Css(CssColors), Xterm(XtermColors), Rgb(u8, u8, u8), } impl crate::private::Sealed for DynColors {} impl DynColor for DynColors { fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DynColors::Ansi(ansi) => ansi.fmt_ansi_fg(f), DynColors::Css(css) => css.fmt_ansi_fg(f), DynColors::Xterm(xterm) => xterm.fmt_ansi_fg(f), &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_ansi_fg(f), } } fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DynColors::Ansi(ansi) => ansi.fmt_ansi_bg(f), DynColors::Css(css) => css.fmt_ansi_bg(f), DynColors::Xterm(xterm) => xterm.fmt_ansi_bg(f), &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_ansi_bg(f), } } fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DynColors::Ansi(ansi) => ansi.fmt_raw_ansi_fg(f), DynColors::Css(css) => css.fmt_raw_ansi_fg(f), DynColors::Xterm(xterm) => xterm.fmt_raw_ansi_fg(f), &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_raw_ansi_fg(f), } } fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DynColors::Ansi(ansi) => ansi.fmt_raw_ansi_bg(f), DynColors::Css(css) => css.fmt_raw_ansi_bg(f), DynColors::Xterm(xterm) => xterm.fmt_raw_ansi_bg(f), &DynColors::Rgb(r, g, b) => Rgb(r, g, b).fmt_raw_ansi_bg(f), } } #[doc(hidden)] fn get_dyncolors_fg(&self) -> crate::DynColors { *self } #[doc(hidden)] fn get_dyncolors_bg(&self) -> crate::DynColors { *self } } /// An error for when the color can not be parsed from a string at runtime #[derive(Debug)] pub struct ParseColorError; impl core::str::FromStr for DynColors { type Err = ParseColorError; fn from_str(s: &str) -> Result { if s.chars().next().ok_or(ParseColorError)? == '#' { match s.len() { 4 => { // TODO Err(ParseColorError) } 7 => Ok(Self::Rgb( u8::from_str_radix(&s[1..3], 16).or(Err(ParseColorError))?, u8::from_str_radix(&s[3..5], 16).or(Err(ParseColorError))?, u8::from_str_radix(&s[5..7], 16).or(Err(ParseColorError))?, )), _ => Err(ParseColorError), } } else { let ansi = match s { "black" => AnsiColors::Black, "red" => AnsiColors::Red, "green" => AnsiColors::Green, "yellow" => AnsiColors::Yellow, "blue" => AnsiColors::Blue, "magenta" | "purple" => AnsiColors::Magenta, "cyan" => AnsiColors::Cyan, "white" => AnsiColors::White, "bright black" => AnsiColors::BrightBlack, "bright red" => AnsiColors::BrightRed, "bright green" => AnsiColors::BrightGreen, "bright yellow" => AnsiColors::BrightYellow, "bright blue" => AnsiColors::BrightBlue, "bright magenta" => AnsiColors::BrightMagenta, "bright cyan" => AnsiColors::BrightCyan, "bright white" => AnsiColors::BrightWhite, _ => return Err(ParseColorError), }; Ok(Self::Ansi(ansi)) } } } owo-colors-4.2.3/src/dyn_styles.rs000064400000000000000000000565321046102023000153020ustar 00000000000000use crate::{AnsiColors, Color, DynColor, DynColors}; use core::fmt; #[cfg(doc)] use crate::OwoColorize; /// A runtime-configurable text effect for use with [`Style`] #[allow(missing_docs)] #[derive(Debug, Copy, Clone)] pub enum Effect { Bold, Dimmed, Italic, Underline, Blink, BlinkFast, Reversed, Hidden, Strikethrough, } macro_rules! color_methods { ($( #[$fg_meta:meta] #[$bg_meta:meta] $color:ident $fg_method:ident $bg_method:ident ),* $(,)?) => { $( #[$fg_meta] #[must_use] pub const fn $fg_method(mut self) -> Self { self.fg = Some(DynColors::Ansi(AnsiColors::$color)); self } #[$fg_meta] #[must_use] pub const fn $bg_method(mut self) -> Self { self.bg = Some(DynColors::Ansi(AnsiColors::$color)); self } )* }; } macro_rules! style_methods { ($(#[$meta:meta] ($name:ident, $set_name:ident)),* $(,)?) => { $( #[$meta] #[must_use] pub const fn $name(mut self) -> Self { self.style_flags = self.style_flags.$set_name(true); self } )* }; } const _: () = (); // workaround for syntax highlighting bug /// A wrapper type which applies a [`Style`] when displaying the inner type pub struct Styled { /// The target value to be styled pub(crate) target: T, /// The style to apply to target pub style: Style, } /// A pre-computed style that can be applied to a struct using [`OwoColorize::style`]. /// /// Its interface mimics that of [`OwoColorize`], but instead of chaining methods on your /// object, you instead chain them on the `Style` object before applying it. /// /// ```rust /// use owo_colors::{OwoColorize, Style}; /// /// let my_style = Style::new() /// .red() /// .on_white() /// .strikethrough(); /// /// println!("{}", "red text, white background, struck through".style(my_style)); /// ``` #[derive(Debug, Copy, Clone, PartialEq)] pub struct Style { pub(crate) fg: Option, pub(crate) bg: Option, pub(crate) bold: bool, pub(crate) style_flags: StyleFlags, } #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq)] pub(crate) struct StyleFlags(pub(crate) u8); impl StyleFlags { #[must_use] #[inline] const fn is_plain(&self) -> bool { self.0 == 0 } } const DIMMED_SHIFT: u8 = 0; const ITALIC_SHIFT: u8 = 1; const UNDERLINE_SHIFT: u8 = 2; const BLINK_SHIFT: u8 = 3; const BLINK_FAST_SHIFT: u8 = 4; const REVERSED_SHIFT: u8 = 5; const HIDDEN_SHIFT: u8 = 6; const STRIKETHROUGH_SHIFT: u8 = 7; macro_rules! style_flags_methods { ($(($shift:ident, $name:ident, $set_name:ident)),* $(,)?) => { $( #[must_use] const fn $name(&self) -> bool { ((self.0 >> $shift) & 1) != 0 } #[must_use] const fn $set_name(mut self, $name: bool) -> Self { self.0 = (self.0 & !(1 << $shift)) | (($name as u8) << $shift); self } )* }; } impl StyleFlags { const fn new() -> Self { Self(0) } style_flags_methods! { (DIMMED_SHIFT, dimmed, set_dimmed), (ITALIC_SHIFT, italic, set_italic), (UNDERLINE_SHIFT, underline, set_underline), (BLINK_SHIFT, blink, set_blink), (BLINK_FAST_SHIFT, blink_fast, set_blink_fast), (REVERSED_SHIFT, reversed, set_reversed), (HIDDEN_SHIFT, hidden, set_hidden), (STRIKETHROUGH_SHIFT, strikethrough, set_strikethrough), } } impl Default for StyleFlags { fn default() -> Self { Self::new() } } impl Style { /// Create a new style to be applied later #[must_use] pub const fn new() -> Self { Self { fg: None, bg: None, bold: false, style_flags: StyleFlags::new(), } } /// Apply the style to a given struct to output. /// /// # Example /// /// Usage in const contexts: /// /// ```rust /// use owo_colors::{OwoColorize, Style, Styled}; /// /// const STYLED_TEXT: Styled<&'static str> = Style::new().bold().italic().style("bold and italic text"); /// /// println!("{}", STYLED_TEXT); /// # assert_eq!(format!("{}", STYLED_TEXT), "\u{1b}[1;3mbold and italic text\u{1b}[0m"); /// ``` pub const fn style(&self, target: T) -> Styled { Styled { target, style: *self, } } /// Set the foreground color generically /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "red foreground".fg::()); /// ``` #[must_use] pub const fn fg(mut self) -> Self { self.fg = Some(C::DYN_COLORS_EQUIVALENT); self } /// Set the background color generically. /// /// ```rust /// use owo_colors::{OwoColorize, colors::*}; /// /// println!("{}", "black background".bg::()); /// ``` #[must_use] pub const fn bg(mut self) -> Self { self.bg = Some(C::DYN_COLORS_EQUIVALENT); self } /// Removes the foreground color from the style. Note that this does not apply /// the default color, but rather represents not changing the current terminal color. /// /// If you wish to actively change the terminal color back to the default, see /// [`Style::default_color`]. #[must_use] pub const fn remove_fg(mut self) -> Self { self.fg = None; self } /// Removes the background color from the style. Note that this does not apply /// the default color, but rather represents not changing the current terminal color. /// /// If you wish to actively change the terminal color back to the default, see /// [`Style::on_default_color`]. #[must_use] pub const fn remove_bg(mut self) -> Self { self.bg = None; self } color_methods! { /// Change the foreground color to black /// Change the background color to black Black black on_black, /// Change the foreground color to red /// Change the background color to red Red red on_red, /// Change the foreground color to green /// Change the background color to green Green green on_green, /// Change the foreground color to yellow /// Change the background color to yellow Yellow yellow on_yellow, /// Change the foreground color to blue /// Change the background color to blue Blue blue on_blue, /// Change the foreground color to magenta /// Change the background color to magenta Magenta magenta on_magenta, /// Change the foreground color to purple /// Change the background color to purple Magenta purple on_purple, /// Change the foreground color to cyan /// Change the background color to cyan Cyan cyan on_cyan, /// Change the foreground color to white /// Change the background color to white White white on_white, /// Change the foreground color to the terminal default /// Change the background color to the terminal default Default default_color on_default_color, /// Change the foreground color to bright black /// Change the background color to bright black BrightBlack bright_black on_bright_black, /// Change the foreground color to bright red /// Change the background color to bright red BrightRed bright_red on_bright_red, /// Change the foreground color to bright green /// Change the background color to bright green BrightGreen bright_green on_bright_green, /// Change the foreground color to bright yellow /// Change the background color to bright yellow BrightYellow bright_yellow on_bright_yellow, /// Change the foreground color to bright blue /// Change the background color to bright blue BrightBlue bright_blue on_bright_blue, /// Change the foreground color to bright magenta /// Change the background color to bright magenta BrightMagenta bright_magenta on_bright_magenta, /// Change the foreground color to bright purple /// Change the background color to bright purple BrightMagenta bright_purple on_bright_purple, /// Change the foreground color to bright cyan /// Change the background color to bright cyan BrightCyan bright_cyan on_bright_cyan, /// Change the foreground color to bright white /// Change the background color to bright white BrightWhite bright_white on_bright_white, } /// Make the text bold #[must_use] pub const fn bold(mut self) -> Self { self.bold = true; self } style_methods! { /// Make the text dim (dimmed, set_dimmed), /// Make the text italicized (italic, set_italic), /// Make the text underlined (underline, set_underline), /// Make the text blink (blink, set_blink), /// Make the text blink (but fast!) (blink_fast, set_blink_fast), /// Swap the foreground and background colors (reversed, set_reversed), /// Hide the text (hidden, set_hidden), /// Cross out the text (strikethrough, set_strikethrough), } #[must_use] const fn set_effect(mut self, effect: Effect, to: bool) -> Self { use Effect::*; match effect { Bold => { self.bold = to; } Dimmed => { // This somewhat contorted construction is required because const fns can't take // mutable refs as of Rust 1.81. self.style_flags = self.style_flags.set_dimmed(to); } Italic => { self.style_flags = self.style_flags.set_italic(to); } Underline => { self.style_flags = self.style_flags.set_underline(to); } Blink => { self.style_flags = self.style_flags.set_blink(to); } BlinkFast => { self.style_flags = self.style_flags.set_blink_fast(to); } Reversed => { self.style_flags = self.style_flags.set_reversed(to); } Hidden => { self.style_flags = self.style_flags.set_hidden(to); } Strikethrough => { self.style_flags = self.style_flags.set_strikethrough(to); } } self } #[must_use] const fn set_effects(mut self, mut effects: &[Effect], to: bool) -> Self { // This is basically a for loop that also works in const contexts. while let [first, rest @ ..] = effects { self = self.set_effect(*first, to); effects = rest; } self } /// Apply a given effect from the style #[must_use] pub const fn effect(self, effect: Effect) -> Self { self.set_effect(effect, true) } /// Remove a given effect from the style #[must_use] pub const fn remove_effect(self, effect: Effect) -> Self { self.set_effect(effect, false) } /// Apply a given set of effects to the style #[must_use] pub const fn effects(self, effects: &[Effect]) -> Self { self.set_effects(effects, true) } /// Remove a given set of effects from the style #[must_use] pub const fn remove_effects(self, effects: &[Effect]) -> Self { self.set_effects(effects, false) } /// Disables all the given effects from the style #[must_use] pub const fn remove_all_effects(mut self) -> Self { self.bold = false; self.style_flags = StyleFlags::new(); self } /// Set the foreground color at runtime. Only use if you do not know which color will be used at /// compile-time. If the color is constant, use either [`OwoColorize::fg`](crate::OwoColorize::fg) or /// a color-specific method, such as [`OwoColorize::green`](crate::OwoColorize::green), /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "green".color(AnsiColors::Green)); /// ``` #[must_use] pub fn color(mut self, color: Color) -> Self { // Can't be const because `get_dyncolors_fg` is a trait method. self.fg = Some(color.get_dyncolors_fg()); self } /// Set the background color at runtime. Only use if you do not know what color to use at /// compile-time. If the color is constant, use either [`OwoColorize::bg`](crate::OwoColorize::bg) or /// a color-specific method, such as [`OwoColorize::on_yellow`](crate::OwoColorize::on_yellow), /// /// ```rust /// use owo_colors::{OwoColorize, AnsiColors}; /// /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow)); /// ``` #[must_use] pub fn on_color(mut self, color: Color) -> Self { // Can't be const because `get_dyncolors_bg` is a trait method. self.bg = Some(color.get_dyncolors_bg()); self } /// Set the foreground color to a specific RGB value. #[must_use] pub const fn fg_rgb(mut self) -> Self { self.fg = Some(DynColors::Rgb(R, G, B)); self } /// Set the background color to a specific RGB value. #[must_use] pub const fn bg_rgb(mut self) -> Self { self.bg = Some(DynColors::Rgb(R, G, B)); self } /// Sets the foreground color to an RGB value. #[must_use] pub const fn truecolor(mut self, r: u8, g: u8, b: u8) -> Self { self.fg = Some(DynColors::Rgb(r, g, b)); self } /// Sets the background color to an RGB value. #[must_use] pub const fn on_truecolor(mut self, r: u8, g: u8, b: u8) -> Self { self.bg = Some(DynColors::Rgb(r, g, b)); self } /// Returns true if the style does not apply any formatting. #[must_use] #[inline] pub const fn is_plain(&self) -> bool { let s = &self; !(s.fg.is_some() || s.bg.is_some() || s.bold) && s.style_flags.is_plain() } /// Returns a formatter for the style's ANSI prefix. /// /// This can be used to separate out the prefix and suffix of a style. /// /// # Example /// /// ``` /// use owo_colors::Style; /// use std::fmt::Write; /// /// let style = Style::new().red().on_blue(); /// let prefix = style.prefix_formatter(); /// let suffix = style.suffix_formatter(); /// /// // Write the prefix and suffix separately. /// let mut output = String::new(); /// write!(output, "{}", prefix); /// output.push_str("Hello"); /// write!(output, "{}", suffix); /// /// assert_eq!(output, "\x1b[31;44mHello\x1b[0m"); /// ``` pub const fn prefix_formatter(&self) -> StylePrefixFormatter { StylePrefixFormatter(*self) } /// Returns a formatter for the style's ANSI suffix. /// /// This can be used to separate out the prefix and suffix of a style. /// /// # Example /// /// See [`Style::prefix_formatter`]. pub const fn suffix_formatter(&self) -> StyleSuffixFormatter { StyleSuffixFormatter(*self) } /// Applies the ANSI-prefix for this style to the given formatter #[inline] #[allow(unused_assignments)] pub fn fmt_prefix(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = self; let format_less_important_effects = s.style_flags != StyleFlags::default(); let format_effect = s.bold || format_less_important_effects; let format_any = !self.is_plain(); let mut semicolon = false; if format_any { f.write_str("\x1b[")?; } if let Some(fg) = s.fg { ::fmt_raw_ansi_fg(&fg, f)?; semicolon = true; } if let Some(bg) = s.bg { if s.fg.is_some() { f.write_str(";")?; } ::fmt_raw_ansi_bg(&bg, f)?; semicolon = true; } if format_effect { if s.bold { if semicolon { f.write_str(";")?; } f.write_str("1")?; semicolon = true; } macro_rules! text_effect_fmt { ($style:ident, $formatter:ident, $semicolon:ident, $(($attr:ident, $value:literal)),* $(,)?) => { $( if $style.style_flags.$attr() { if $semicolon { $formatter.write_str(";")?; } $formatter.write_str($value)?; $semicolon = true; } )+ } } if format_less_important_effects { text_effect_fmt! { s, f, semicolon, (dimmed, "2"), (italic, "3"), (underline, "4"), (blink, "5"), (blink_fast, "6"), (reversed, "7"), (hidden, "8"), (strikethrough, "9"), } } } if format_any { f.write_str("m")?; } Ok(()) } /// Applies the ANSI-suffix for this style to the given formatter #[inline] pub fn fmt_suffix(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.is_plain() { f.write_str("\x1b[0m")?; } Ok(()) } } /// Formatter for the prefix of a [`Style`]. /// /// This is used to get the ANSI escape codes for the style without /// the suffix, which is useful for formatting the prefix separately. #[derive(Debug, Clone, Copy, PartialEq)] #[must_use = "this formatter does nothing unless displayed"] pub struct StylePrefixFormatter(Style); impl fmt::Display for StylePrefixFormatter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt_prefix(f) } } /// Formatter for the suffix of a [`Style`]. /// /// This is used to get the ANSI escape codes for the style without /// the prefix, which is useful for formatting the suffix separately. #[derive(Debug, Clone, Copy, PartialEq)] #[must_use = "this formatter does nothing unless displayed"] pub struct StyleSuffixFormatter(Style); impl fmt::Display for StyleSuffixFormatter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt_suffix(f) } } impl Default for Style { fn default() -> Self { Self::new() } } /// Helper to create [`Style`]s more ergonomically pub const fn style() -> Style { Style::new() } impl Styled { /// Returns a reference to the inner value to be styled pub const fn inner(&self) -> &T { &self.target } /// Returns a mutable reference to the inner value to be styled. /// /// *This method is const on Rust 1.83+.* #[cfg(const_mut_refs)] pub const fn inner_mut(&mut self) -> &mut T { &mut self.target } /// Returns a mutable reference to the inner value to be styled. /// /// *This method is const on Rust 1.83+.* #[cfg(not(const_mut_refs))] pub fn inner_mut(&mut self) -> &mut T { &mut self.target } } macro_rules! impl_fmt { ($($trait:path),* $(,)?) => { $( impl $trait for Styled { #[allow(unused_assignments)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.style.fmt_prefix(f)?; ::fmt(&self.target, f)?; self.style.fmt_suffix(f) } } )* }; } impl_fmt! { fmt::Display, fmt::Debug, fmt::UpperHex, fmt::LowerHex, fmt::Binary, fmt::UpperExp, fmt::LowerExp, fmt::Octal, fmt::Pointer, } #[cfg(test)] mod tests { use super::*; use crate::{AnsiColors, OwoColorize}; #[test] fn size_of() { let size = std::mem::size_of::