easy_sgr/lib.rs
1//! An easy-to-use library for adding graphical ANSI codes or [`SGR`][SGR] escape sequences to your project.
2//! Its main strengths are the multitude of methods that are provided,
3//! and the lack of dependencies; compile times should be pretty good.
4//!
5//! This library does not support the usage of non-[`SGR`][SGR] ANSI escape sequences
6//!
7//! ## Installation
8//!
9//! Add this to your Cargo.toml:
10//!
11//! ```toml
12//! [dependencies]
13//! easy-sgr="0.1.1"
14//! ```
15//!
16//! ## Usage
17//!
18//! ### `Macros`
19//!
20//! The method I would recommend when regarding ease-of-use is to use the macros provided,
21//! through this library or the macro library [itself](https://docs.rs/easy-sgr/latest/easy_sgr_macros/).
22//!
23//! This can be done without importing any other features of the library as such:
24//!
25//! ```toml
26//! [dependencies]
27//! easy-sgr = { version = "0.1.1", features = ["macro-only"] }
28//! ```
29//!
30//! Or if you want to still use the other features, replace `"macro-only"` with `"macros"`.
31//!
32//! And its usage is very simple:
33//!
34//! ```rust
35//! use easy_sgr::println;
36//!
37//! println!("{[italic red]}This should be italic & red!{[]}");
38//! ```
39//!
40//! `{[]}` is interpreted as a reset here.
41//!
42//! All the other `fmt` functions are also implemented, see
43//! [`easy-sgr-macros`](https://docs.rs/easy-sgr/latest/easy_sgr_macros/) for more.
44//!
45//! ### `Color` and `Style` enums
46//!
47//! The simplest runtime way to color text, using these two enums allows you to
48//! work inline of a string literal when using a macro such as
49//! `println!`, `writeln!` or `format!`:
50//!
51//! ```rust
52//! use easy_sgr::{Color::*, Style::*};
53//!
54//! println!("{Italic}{RedFg}This should be italic & red!{Reset}");
55//! ```
56//!
57//! `Color` and `Style` are both enums that implement `Display`: when they
58//! are printed a matching [`SGR`][SGR] code is written.
59//!
60//! This method is the best when it comes to simplicity, but has drawbacks;
61//! using it rewrites the sequence escape `\x1b[` and the sequence end `m` repeatedly.
62//! In this example this is what would be written:
63//!
64//! ```plain
65//! \x1b[3m\x1b[31mThis should be italic & red!\x1b[0m
66//! ```
67//!
68//! This would not be much of an issue for the vast majority of use cases.
69//!
70//! ### `EasySGR` trait
71//!
72//! This is similar to the method above but uses the `EasySGR` trait.
73//! This trait is implemented by anything that implements Into\<AnsiString\> including Style and Color.
74//! Its main purpose is to provide functions for chaining [`SGR`][SGR] codes.
75//!
76//! The example above can be achieved using it as such:
77//!
78//! ```rust
79//! use easy_sgr::{ Color::*, EasySGR, Style::*};
80//!
81//! let sgr = Italic.color(RedFg);
82//!
83//! println!("{sgr}This should be italic & red!{Reset}");
84//! ```
85//!
86//! Now the output would look something like this:
87//!
88//! ```plain
89//! \x1b[31;3mThis should be italic & red!\x1b[0m
90//! ```
91//!
92//! Instead of a rewriting the entire sequence, the separator character `;` is used instead.
93//!
94//! Doing this avoids the issue of rewriting the Escape and End sequences,
95//! though is more expensive to use as it allocates an `SGRString`.
96//!
97//! ### `SGRString` struct
98//!
99//! `SGRString` is the type returned by all `EasySGR` functions, it encapsulates all
100//! possible [`SGR`][SGR] sequences. You can use it to reproduce the previous examples as such:
101//!
102//! ```rust
103//! use easy_sgr::{Color::*, EasySGR, Style::*};
104//!
105//! let text = "This should be italic & red!"
106//! .to_sgr()
107//! .style(Italic)
108//! .color(RedFg);
109//! println!("{text}");
110//! ```
111//!
112//! You can forgo `.to_sgr()` as `.style(..)`, `.color(..)` and all other `EasySGR` functions
113//! can be directly called on the string literal and other types that implement it.
114//!
115//! The method above still uses the `EasySGR` trait, you can go without it like here:
116//!
117//! ```rust
118//! use easy_sgr::{ColorKind, SGRString, StyleKind};
119//!
120//! let mut text = SGRString::from("This should be italic & red!");
121//! text.italic = StyleKind::Place;
122//! text.foreground = ColorKind::Red;
123//!
124//! println!("{text}")
125//! ```
126//!
127//! ### `SGRWriter` struct
128//!
129//! The writer can also be used directly, instead of using the above methods:
130//!
131//! ```rust
132//! use std::io::{stdout, Write};
133//! use easy_sgr::{Color::*, EasySGR, SGRWriter, Style::*};
134//!
135//! let mut writer = SGRWriter::from(stdout());
136//! writer.sgr(&Italic.color(RedFg)).unwrap();
137//! writer.write_inner("This should be italic & red!").unwrap();
138//! writer.sgr(&Reset).unwrap();
139//! ```
140//!
141//! or, when writing to a String
142//!
143//! ```rust
144//! use easy_sgr::{Color::*, EasySGR, SGRWriter, Style::*};
145//!
146//! let stylized_string = {
147//! let mut writer = SGRWriter::from(String::new());
148//! writer.sgr(&Italic.color(RedFg)).unwrap();
149//! writer.write_inner("This should be italic & red!").unwrap();
150//! writer.sgr(&Reset).unwrap();
151//! writer.internal()
152//! };
153//! ```
154//!
155//! ## Features
156//!
157//! ### `partial`
158//!
159//! This feature changes the way that the `discrete` module works,
160//! enabling it causes it's types to not write the sequence escape and end.
161//!
162//! This means to achieve the same affect as above you must do this:
163//!
164//! ```rust
165//! use easy_sgr::{Color::*, Seq::*, Style::*};
166//!
167//! println!("{Esc}{Italic};{RedFg}{End}This should be italic & red!{Esc}{Reset}{End}");
168//! ```
169//!
170//! resulting in the string:
171//!
172//! ```plain
173//! \x1b[3;31mThis should be italic & red!\x1b[0m
174//! ```
175//!
176//! This feature exchanges ease of use for verbosity, resulting in more control.
177//!
178//! ## Structure
179//!
180//! easy-sgr is split into three modules:
181//!
182//! - discrete
183//! - Contains types that can be used inline of a string literal
184//! - The types, `Seq`, `Color` & `Style` are all able to function independently
185//! - They all implement the `DiscreteSGR` type to aid in this
186//! - The `DiscreteSGR` types can all work with an `SGRString`
187//! - graphics
188//! - Centerpiece is `SGRString` & `EasySGR`
189//! - `SGRString` is a `String` with the ability to write [`SGR`][SGR] codes
190//! - `EasySGR` is a trait for chaining [`SGR`][SGR] codes to create a `SGRString`
191//! - `EasySGR` is blanket implemented by everything that implements `Into<SGRString>`
192//! - This includes:
193//! - `SGRString`
194//! - `Color`
195//! - `Style`
196//! - `&str`
197//! - `String`
198//! - `&String`
199//! - writing
200//! - Implements `SGRWriter` & `SGRBuilder`
201//! - Used by other modules to do writing
202//!
203//! Though no modules really will be seen in usage,
204//! as all the types they contain are reexported.
205//!
206//! [SGR]: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR
207//!
208//! ## TODO for `1.0.0` release
209//!
210//! - [ ] Add examples to docs
211//! - [x] `discrete`
212//! - [ ] `graphics`
213//! - [ ] `writing`
214//! - [x] Macros (`east-sgr-macros`) (`0.1.0`)
215//! - [ ] Add parser?
216//! - [ ] Add parsing from ansi codes
217//! - [ ] Add parsing for `SGRString`
218//! - [ ] `EasySGR` implementation that doesn't allocate an `SGRString`
219#![forbid(unsafe_code)]
220#![deny(
221 clippy::all,
222 clippy::pedantic,
223 clippy::cargo,
224 clippy::nursery,
225 missing_docs,
226 rustdoc::all,
227 future_incompatible
228)]
229#![warn(missing_debug_implementations)]
230#![allow(clippy::enum_glob_use)]
231/// Implements SGR types that can be used standalone of a [`SGRString`]
232///
233/// These types exist outside the context of a [`SGRString`], but
234/// can be used in conjunction of one through the use of [`EasySGR`]
235#[cfg(not(feature = "macro-only"))]
236pub mod discrete;
237/// Contains the standard SGR implementations.
238///
239/// Makes use of the [`writers`](writing) to write `SGR` codes to a writer
240#[cfg(not(feature = "macro-only"))]
241pub mod graphics;
242/// Contains various structs and traits to help in writing `SGR` codes
243#[cfg(not(feature = "macro-only"))]
244pub mod writing;
245
246#[cfg(not(feature = "macro-only"))]
247pub use self::{discrete::*, graphics::*, writing::*};
248
249#[cfg(feature = "macros")]
250pub use easy_sgr_macros::*;