Expand description
fluent-ansi is a library to handle ANSI escape sequences for the terminal.
It is no_std, and relies on the Display trait to render the sequences.
use fluent_ansi::{prelude::*, Style, Styled};
let style: Style = Color::RED.bold();
let styled: Styled<&str> = style.applied_to("Some content");
println!("{}", styled);
let content_with_escape_sequences = format!("{}", styled);
assert_eq!(content_with_escape_sequences, "\x1b[1;31mSome content\x1b[0m");It has modular and composable values, and with its fluent methods, it provides several forms to
reach the same result. For instance, all the lines below result in the same Style value:
use fluent_ansi::{prelude::*, ColorTarget, Style, TargetedColor};
let style: Style = Style::new().set(Effect::Bold, true).set(ColorTarget::Foreground, Some(Color::RED.to_color()));
let style: Style = Style::new().set_effect(Effect::Bold, true).set_color(ColorTarget::Foreground, Some(Color::RED));
let style: Style = Style::new().add(Effect::Bold).add(TargetedColor::new(Color::RED, ColorTarget::Foreground));
let style: Style = Style::new().effect(Effect::Bold).color(TargetedColor::new(Color::RED, ColorTarget::Foreground));
let style: Style = Style::new().bold().fg(Color::RED);
let style: Style = Effect::Bold.fg(Color::RED);
let style: Style = Color::RED.for_fg().bold();All styling types are immutable and implement Copy, except for Styled<C>,
which is copiable only if its content C type is also copiable.
§Styling types
The styling types are categorized according to the following:
- Styling element types:
- Effect types:
- Color types:
TargetedColor- The color types in
color
- Composed styling types:
§Styling element types
Each styling element type represents a single styling. They can be used on their own or – through their fluent methods – combined with other styling elements, or applied to some content:
use fluent_ansi::prelude::*;
assert_eq!(format!("{}", Effect::Bold), "\x1b[1m");
assert_eq!(format!("{}", Effect::Bold.fg(Color::RED)), "\x1b[1;31m");
assert_eq!(format!("{}", Effect::Bold.applied_to("Some content")), "\x1b[1mSome content\x1b[0m");When composed, they result in the Style composed styling type.
When applied to some content, they result in the Styled<C> composed styling type.
§Effect types
An effect is an styling element type that may or may not be present. They correspond to the variants in the Effect enum.
A subset of effects correspond to underline effects. They are mutually exclusive, meaning that when one of them is set, any previously set underline effect is cleared.
use fluent_ansi::prelude::*;
let style = Effect::Bold.add(Effect::DottedUnderline);
assert!(style.get_effect(Effect::Bold));
assert!(style.get_effect(Effect::DottedUnderline));
let style = style.add(Effect::DashedUnderline);
assert!(style.get_effect(Effect::Bold));
assert!(!style.get_effect(Effect::DottedUnderline));
assert!(style.get_effect(Effect::DashedUnderline));The UnderlineEffect enum variants represent the underline effects.
§Color types
There is a handful of color types, which are defined in the color module.
A color is rendered in a ColorTarget, which is Foreground,
Background or Underline.
The type TargetedColor associates a color with a ColorTarget:
use fluent_ansi::{prelude::*, TargetedColor};
let red_foreground: TargetedColor = Color::RED.for_fg();
assert_eq!(format!("{}", red_foreground.applied_to("Some content")), "\x1b[31mSome content\x1b[0m");
let red_background: TargetedColor = Color::RED.for_bg();
assert_eq!(format!("{}", red_background.applied_to("Some content")), "\x1b[41mSome content\x1b[0m");
let red_underline: TargetedColor = Color::RED.for_underline();
assert_eq!(format!("{}", red_underline.applied_to("Some content")), "\x1b[58;5;1mSome content\x1b[0m");By default, colors are rendered in the foreground:
use fluent_ansi::prelude::*;
let rendered_1 = format!("{}", Color::RED.applied_to("Some content"));
let rendered_2 = format!("{}", Color::RED.for_fg().applied_to("Some content"));
assert_eq!(rendered_1, rendered_2);
assert_eq!(rendered_1, "\x1b[31mSome content\x1b[0m");You can refrain from mentioning the color target when using only in the foreground. But if another color target is being used too, be explicit about the foreground target:
use fluent_ansi::prelude::*;
// Only the foreground is set
let style = Effect::Bold.add(Color::RED);
let rendered = format!("{}", style.applied_to("Some content"));
assert_eq!(rendered, "\x1b[1;31mSome content\x1b[0m");
// Both foreground and underline colors are set
let style = Effect::Bold
.add(Color::RED.for_fg())
.add(Color::indexed(42).for_underline());
let rendered = format!("{}", style.applied_to("Some content"));
assert_eq!(rendered, "\x1b[1;31;58;5;42mSome content\x1b[0m");§Composed styling types
Style is the result of composing styling element values. A Style can be used on its own or – through
their methods – compose with other styling elements, or applied to some content:
use fluent_ansi::{prelude::*, Style};
let style: Style = Effect::Bold.fg(Color::RED);
assert_eq!(format!("{style}"), "\x1b[1;31m");
let style: Style = style.effect(Effect::SolidUnderline);
assert_eq!(format!("{style}"), "\x1b[1;4;31m");
let styled = style.applied_to("Some content");
assert_eq!(format!("{styled}"), "\x1b[1;4;31mSome content\x1b[0m");Styled<C> includes a Style and some content to have the styling applied to. The content can
be any type that implements Display. When rendered, the content is preceded by the
escape sequence corresponding to the styling, and is succeeded by the escape sequence that resets the styling.
A Styled<C> instance is obtained with the applied_to() method available in any styling element type
and in Style, or with Styled<C>::new() to create an instance without any styling.
use fluent_ansi::{prelude::*, Styled};
assert_eq!(format!("{}", Effect::Bold.applied_to("Some content")), "\x1b[1mSome content\x1b[0m");
assert_eq!(format!("{}", Color::RED.applied_to("Some content")), "\x1b[31mSome content\x1b[0m");
assert_eq!(format!("{}", Color::RED.bold().applied_to("Some content")), "\x1b[1;31mSome content\x1b[0m");
assert_eq!(format!("{}", Styled::new("Some content").bold().fg(Color::RED)), "\x1b[1;31mSome content\x1b[0m");§Styling methods
Since all types are immutable, all methods return a new value, that is a composed styling type, which is:
Styled<C>when the method is called from that type,Stylewhen the method is called from any other type.
There are three group of methods, according to how styling is handled:
- fluent methods
- methods for handling styling as elements and sets
- methods for handling styling as attributes
In the methods docs below, the links take to their implementation in Style, but they are the same for all types.
Although some methods below are documented with varying signatures (e.g. color(TargetedColor) and color(impl Into<Color>)),
each method name has a single implementation with a generic argument in each type. Check the linked method documentation to see
the real signature.
§Fluent methods
The fluent methods allow to compose/add/set styling. They are available in all styling types.
| Method | To set what |
|---|---|
bold(),italic(),solid_underline(),etc. | effect |
effect(impl Into<Effect>) | effect (including underline effects) |
underline_effect(UnderlineEffect) | underline effect |
fg(impl Into<Color>)bg(impl Into<Color>)underline_color(impl Into<Color>) | color |
color(TargetedColor) | color |
color(impl Into<Color>) | foreground color |
applied_to(impl Display) 1 | content |
§Methods for elements and sets
All styling types can be viewed as styling sets where styling elements can be added to or removed from.
The add method adds an element to a set, and the remove method removes an element from a set.
§The add method
The add method can be used to compose/add/set some styling, and is available in all styling types.
| Method | To add what |
|---|---|
add(Effect) | effect |
add(UnderlineEffect) | underline effect |
add(TargetedColor) | color |
add(impl Into<Color>) | foreground color |
§The remove method
The remove method can be used to clear/remove some styling, and is available in the composed styling types.
| Method | To remove what | Note |
|---|---|---|
remove(Effect) | effect | |
remove(UnderlineEffect) | underline effect | Remove the specific effect, if set |
remove(UnderlineStyle) | underline effect | Remove any underline effect that may be set |
remove(ColorTarget) | color |
§Example
use fluent_ansi::{prelude::*, ColorTarget, UnderlineStyle, Styled};
let styled = Styled::new("Some content")
.add(Effect::Bold)
.add(Effect::DottedUnderline)
.add(Color::RED.for_underline());
assert_eq!(format!("{styled}"), "\x1b[1;4:4;58;5;1mSome content\x1b[0m");
// ...
let altered_styled = styled
.remove(UnderlineStyle)
.remove(ColorTarget::Underline)
.add(Color::indexed(42).for_bg());
assert_eq!(format!("{altered_styled}"), "\x1b[1;48;5;42mSome content\x1b[0m");§Methods for attributes
Styling can be seen as attributes, which have values. The type of the value varies according to the attribute.
| Attribute | Value type | Meaning |
|---|---|---|
Effect | bool | Whether the effect is set or not |
UnderlineEffect | bool | Whether the specific underline effect is set or not |
UnderlineStyle | Option<UnderlineEffect> | Which underline effect is in use, if any |
ColorTarget | Option<Color> | Which color is in use for that target, if any |
The set method can be used to add/set/clear/remove some styling, and the get method can be used to query any styling.
Both methods are available in all composed styling types.
There are also styling-specific variations for the set and get methods, in addition to the get_effects(), that returns an
iterator on the effects that are set.
§Example
use fluent_ansi::{prelude::*, ColorTarget, UnderlineStyle, Styled};
let styled = Styled::new("Some content")
.set(Effect::Bold, true)
.set(Effect::DottedUnderline, true)
.set(ColorTarget::Underline, Some(Color::RED.to_color()));
assert_eq!(format!("{styled}"), "\x1b[1;4:4;58;5;1mSome content\x1b[0m");
// ...
let altered_styled = styled
.set(UnderlineStyle, None)
.set(ColorTarget::Underline, None)
.set(ColorTarget::Background, Some(Color::indexed(42).to_color()));
assert_eq!(format!("{altered_styled}"), "\x1b[1;48;5;42mSome content\x1b[0m");§The Reset singleton
Reset is a singleton value that represents the “reset” ANSI code. It can be used to manually control
the starting and ending escape sequences instead of using the Styled<C> type with an enclosed content.
use fluent_ansi::{prelude::*, Reset};
let style = Color::RED.bold();
let output = format!("{style}Some content{Reset}");
assert_eq!(output, "\x1b[1;31mSome content\x1b[0m");applied_to()is not available inStyled<C>values, and always returns aStyled<C>. ↩To clear a color with
set_color(), the color type must be specified in theNonevalue as e.g.None::<Color>. As an alternative, use theColor::none()method. ↩
Modules§
Structs§
- GetEffects
- An iterator over the effects that are currently set.
- Reset
- A type that represents the reset of all styling.
- Style
- A structure representing text styling with effects and colors.
- Styled
- A value that associates some content with a specific style.
- Targeted
Color - A color in a specific color target.
- Underline
Style - The underline attribute.
Enums§
- Color
Target - The target where a color is applied.
- Effect
- An enumeration of all supported text styling effects.
- Underline
Effect - An enumeration of all supported underline effects.
Traits§
- Styling
Attribute - A trait to represent an attribute that can be set in or retrieved from any composed styling value.
- Styling
Element - An element that can be composed with any styling type.