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

pub use discrete::*;
pub use graphics::*;
pub use writing::*;