Direct write command ansi_codes (#390)
This commit is contained in:
parent
e620c6b8be
commit
9c9479deb2
@ -132,7 +132,7 @@ fn draw_cursor_box<W, F, T>(w: &mut W, description: &str, cursor_command: F) ->
|
|||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
F: Fn(u16, u16) -> T,
|
F: Fn(u16, u16) -> T,
|
||||||
T: Command<AnsiType = String>,
|
T: Command,
|
||||||
{
|
{
|
||||||
execute!(
|
execute!(
|
||||||
w,
|
w,
|
||||||
|
4
src/ansi.rs
Normal file
4
src/ansi.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/// Wrapper type for write dynamic ansi string
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct Ansi<T>(pub T);
|
113
src/cursor.rs
113
src/cursor.rs
@ -46,7 +46,8 @@ pub use sys::position;
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::{impl_display, Command};
|
use crate::{impl_display, Ansi, Command};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
mod ansi;
|
mod ansi;
|
||||||
pub(crate) mod sys;
|
pub(crate) mod sys;
|
||||||
@ -60,11 +61,18 @@ pub(crate) mod sys;
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveTo(pub u16, pub u16);
|
pub struct MoveTo(pub u16, pub u16);
|
||||||
|
|
||||||
impl Command for MoveTo {
|
impl fmt::Display for Ansi<MoveTo> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_to_csi_sequence(f, (self.0).0, (self.0).1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveTo {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_to_csi_sequence(self.0, self.1)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -82,11 +90,18 @@ impl Command for MoveTo {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveToNextLine(pub u16);
|
pub struct MoveToNextLine(pub u16);
|
||||||
|
|
||||||
impl Command for MoveToNextLine {
|
impl fmt::Display for Ansi<MoveToNextLine> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_to_next_line_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveToNextLine {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_to_next_line_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -104,11 +119,18 @@ impl Command for MoveToNextLine {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveToPreviousLine(pub u16);
|
pub struct MoveToPreviousLine(pub u16);
|
||||||
|
|
||||||
impl Command for MoveToPreviousLine {
|
impl fmt::Display for Ansi<MoveToPreviousLine> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_to_previous_line_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveToPreviousLine {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_to_previous_line_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -125,11 +147,18 @@ impl Command for MoveToPreviousLine {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveToColumn(pub u16);
|
pub struct MoveToColumn(pub u16);
|
||||||
|
|
||||||
impl Command for MoveToColumn {
|
impl fmt::Display for Ansi<MoveToColumn> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_to_column_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveToColumn {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_to_column_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -146,11 +175,18 @@ impl Command for MoveToColumn {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveUp(pub u16);
|
pub struct MoveUp(pub u16);
|
||||||
|
|
||||||
impl Command for MoveUp {
|
impl fmt::Display for Ansi<MoveUp> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_up_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveUp {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_up_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -167,11 +203,18 @@ impl Command for MoveUp {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveRight(pub u16);
|
pub struct MoveRight(pub u16);
|
||||||
|
|
||||||
impl Command for MoveRight {
|
impl fmt::Display for Ansi<MoveRight> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_right_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveRight {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_right_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -188,11 +231,18 @@ impl Command for MoveRight {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveDown(pub u16);
|
pub struct MoveDown(pub u16);
|
||||||
|
|
||||||
impl Command for MoveDown {
|
impl fmt::Display for Ansi<MoveDown> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_down_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveDown {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_down_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -209,11 +259,18 @@ impl Command for MoveDown {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct MoveLeft(pub u16);
|
pub struct MoveLeft(pub u16);
|
||||||
|
|
||||||
impl Command for MoveLeft {
|
impl fmt::Display for Ansi<MoveLeft> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::move_left_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for MoveLeft {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::move_left_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -236,6 +293,7 @@ pub struct SavePosition;
|
|||||||
impl Command for SavePosition {
|
impl Command for SavePosition {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::SAVE_POSITION_CSI_SEQUENCE
|
ansi::SAVE_POSITION_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
@ -260,6 +318,7 @@ pub struct RestorePosition;
|
|||||||
impl Command for RestorePosition {
|
impl Command for RestorePosition {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::RESTORE_POSITION_CSI_SEQUENCE
|
ansi::RESTORE_POSITION_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
@ -281,6 +340,7 @@ pub struct Hide;
|
|||||||
impl Command for Hide {
|
impl Command for Hide {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::HIDE_CSI_SEQUENCE
|
ansi::HIDE_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
@ -302,6 +362,7 @@ pub struct Show;
|
|||||||
impl Command for Show {
|
impl Command for Show {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::SHOW_CSI_SEQUENCE
|
ansi::SHOW_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
@ -324,6 +385,7 @@ pub struct EnableBlinking;
|
|||||||
impl Command for EnableBlinking {
|
impl Command for EnableBlinking {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::ENABLE_BLINKING_CSI_SEQUENCE
|
ansi::ENABLE_BLINKING_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
@ -346,6 +408,7 @@ pub struct DisableBlinking;
|
|||||||
impl Command for DisableBlinking {
|
impl Command for DisableBlinking {
|
||||||
type AnsiType = &'static str;
|
type AnsiType = &'static str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::DISABLE_BLINKING_CSI_SEQUENCE
|
ansi::DISABLE_BLINKING_CSI_SEQUENCE
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,38 @@
|
|||||||
//! This module provides cursor related ANSI escape codes.
|
//! This module provides cursor related ANSI escape codes.
|
||||||
|
|
||||||
use crate::csi;
|
use crate::csi;
|
||||||
|
use std::fmt::{self, Formatter};
|
||||||
|
|
||||||
pub(crate) fn move_to_csi_sequence(x: u16, y: u16) -> String {
|
pub(crate) fn move_to_csi_sequence(f: &mut Formatter, x: u16, y: u16) -> fmt::Result {
|
||||||
format!(csi!("{};{}H"), y + 1, x + 1)
|
write!(f, csi!("{};{}H"), y + 1, x + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_up_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_up_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}A"), count)
|
write!(f, csi!("{}A"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_right_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_right_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}C"), count)
|
write!(f, csi!("{}C"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_down_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_down_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}B"), count)
|
write!(f, csi!("{}B"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_left_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_left_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}D"), count)
|
write!(f, csi!("{}D"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_to_column_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_to_column_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}G"), count)
|
write!(f, csi!("{}G"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_to_previous_line_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_to_previous_line_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}F"), count)
|
write!(f, csi!("{}F"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn move_to_next_line_csi_sequence(count: u16) -> String {
|
pub(crate) fn move_to_next_line_csi_sequence(f: &mut Formatter, count: u16) -> fmt::Result {
|
||||||
format!(csi!("{}E"), count)
|
write!(f, csi!("{}E"), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const SAVE_POSITION_CSI_SEQUENCE: &str = "\x1B7";
|
pub(crate) const SAVE_POSITION_CSI_SEQUENCE: &str = "\x1B7";
|
||||||
|
@ -228,6 +228,7 @@
|
|||||||
//! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
|
//! [flush]: https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.flush
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
|
ansi::Ansi,
|
||||||
command::{Command, ExecutableCommand, QueueableCommand},
|
command::{Command, ExecutableCommand, QueueableCommand},
|
||||||
error::{ErrorKind, Result},
|
error::{ErrorKind, Result},
|
||||||
};
|
};
|
||||||
@ -241,6 +242,7 @@ pub mod style;
|
|||||||
/// A module to work with the terminal.
|
/// A module to work with the terminal.
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
|
|
||||||
|
mod ansi;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub(crate) mod ansi_support;
|
pub(crate) mod ansi_support;
|
||||||
mod command;
|
mod command;
|
||||||
|
52
src/style.rs
52
src/style.rs
@ -114,7 +114,8 @@ use std::{env, fmt::Display};
|
|||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::{impl_display, Command};
|
use crate::{impl_display, Ansi, Command};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub(crate) use self::enums::Colored;
|
pub(crate) use self::enums::Colored;
|
||||||
pub use self::{
|
pub use self::{
|
||||||
@ -284,11 +285,18 @@ pub fn available_color_count() -> u16 {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct SetForegroundColor(pub Color);
|
pub struct SetForegroundColor(pub Color);
|
||||||
|
|
||||||
impl Command for SetForegroundColor {
|
impl fmt::Display for Ansi<SetForegroundColor> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::set_fg_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for SetForegroundColor {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::set_fg_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -307,11 +315,18 @@ impl Command for SetForegroundColor {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct SetBackgroundColor(pub Color);
|
pub struct SetBackgroundColor(pub Color);
|
||||||
|
|
||||||
impl Command for SetBackgroundColor {
|
impl fmt::Display for Ansi<SetBackgroundColor> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::set_bg_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for SetBackgroundColor {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::set_bg_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -330,11 +345,18 @@ impl Command for SetBackgroundColor {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct SetAttribute(pub Attribute);
|
pub struct SetAttribute(pub Attribute);
|
||||||
|
|
||||||
impl Command for SetAttribute {
|
impl fmt::Display for Ansi<SetAttribute> {
|
||||||
type AnsiType = String;
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::set_attr_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for SetAttribute {
|
||||||
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::set_attr_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
@ -354,11 +376,17 @@ impl Command for SetAttribute {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct SetAttributes(pub Attributes);
|
pub struct SetAttributes(pub Attributes);
|
||||||
|
|
||||||
|
impl fmt::Display for Ansi<SetAttributes> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
ansi::set_attrs_csi_sequence(f, (self.0).0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Command for SetAttributes {
|
impl Command for SetAttributes {
|
||||||
type AnsiType = String;
|
type AnsiType = Ansi<Self>;
|
||||||
|
|
||||||
fn ansi_code(&self) -> Self::AnsiType {
|
fn ansi_code(&self) -> Self::AnsiType {
|
||||||
ansi::set_attrs_csi_sequence(self.0)
|
Ansi(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -6,93 +6,75 @@ use crate::{
|
|||||||
style::{Attribute, Attributes, Color, Colored},
|
style::{Attribute, Attributes, Color, Colored},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn set_fg_csi_sequence(fg_color: Color) -> String {
|
use std::fmt::{self, Formatter};
|
||||||
format!(
|
|
||||||
csi!("{}m"),
|
pub(crate) fn set_fg_csi_sequence(f: &mut Formatter, fg_color: Color) -> fmt::Result {
|
||||||
Into::<String>::into(Colored::ForegroundColor(fg_color))
|
write!(f, csi!("{}m"), Colored::ForegroundColor(fg_color))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_bg_csi_sequence(bg_color: Color) -> String {
|
pub(crate) fn set_bg_csi_sequence(f: &mut Formatter, bg_color: Color) -> fmt::Result {
|
||||||
format!(
|
write!(f, csi!("{}m"), Colored::BackgroundColor(bg_color))
|
||||||
csi!("{}m"),
|
|
||||||
Into::<String>::into(Colored::BackgroundColor(bg_color))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_attr_csi_sequence(attribute: Attribute) -> String {
|
pub(crate) fn set_attr_csi_sequence(f: &mut Formatter, attribute: Attribute) -> fmt::Result {
|
||||||
format!(csi!("{}m"), attribute.sgr())
|
write!(f, csi!("{}m"), attribute.sgr())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_attrs_csi_sequence(attributes: Attributes) -> String {
|
pub(crate) fn set_attrs_csi_sequence(f: &mut Formatter, attributes: Attributes) -> fmt::Result {
|
||||||
let mut ansi = String::new();
|
|
||||||
for attr in Attribute::iterator() {
|
for attr in Attribute::iterator() {
|
||||||
if attributes.has(attr) {
|
if attributes.has(attr) {
|
||||||
ansi.push_str(&format!(csi!("{}m"), attr.sgr()));
|
write!(f, csi!("{}m"), attr.sgr())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ansi
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const RESET_CSI_SEQUENCE: &str = csi!("0m");
|
pub(crate) const RESET_CSI_SEQUENCE: &str = csi!("0m");
|
||||||
|
|
||||||
impl From<Colored> for String {
|
impl fmt::Display for Colored {
|
||||||
fn from(colored: Colored) -> Self {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
let mut ansi_value = String::new();
|
|
||||||
|
|
||||||
let color;
|
let color;
|
||||||
|
|
||||||
match colored {
|
match *self {
|
||||||
Colored::ForegroundColor(new_color) => {
|
Colored::ForegroundColor(new_color) => {
|
||||||
if new_color == Color::Reset {
|
if new_color == Color::Reset {
|
||||||
ansi_value.push_str("39");
|
return f.write_str("39");
|
||||||
return ansi_value;
|
|
||||||
} else {
|
} else {
|
||||||
ansi_value.push_str("38;");
|
f.write_str("38;")?;
|
||||||
color = new_color;
|
color = new_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Colored::BackgroundColor(new_color) => {
|
Colored::BackgroundColor(new_color) => {
|
||||||
if new_color == Color::Reset {
|
if new_color == Color::Reset {
|
||||||
ansi_value.push_str("49");
|
return f.write_str("49");
|
||||||
return ansi_value;
|
|
||||||
} else {
|
} else {
|
||||||
ansi_value.push_str("48;");
|
f.write_str("48;")?;
|
||||||
color = new_color;
|
color = new_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let color_val = match color {
|
match color {
|
||||||
Color::Black => "5;0",
|
Color::Black => f.write_str("5;0"),
|
||||||
Color::DarkGrey => "5;8",
|
Color::DarkGrey => f.write_str("5;8"),
|
||||||
Color::Red => "5;9",
|
Color::Red => f.write_str("5;9"),
|
||||||
Color::DarkRed => "5;1",
|
Color::DarkRed => f.write_str("5;1"),
|
||||||
Color::Green => "5;10",
|
Color::Green => f.write_str("5;10"),
|
||||||
Color::DarkGreen => "5;2",
|
Color::DarkGreen => f.write_str("5;2"),
|
||||||
Color::Yellow => "5;11",
|
Color::Yellow => f.write_str("5;11"),
|
||||||
Color::DarkYellow => "5;3",
|
Color::DarkYellow => f.write_str("5;3"),
|
||||||
Color::Blue => "5;12",
|
Color::Blue => f.write_str("5;12"),
|
||||||
Color::DarkBlue => "5;4",
|
Color::DarkBlue => f.write_str("5;4"),
|
||||||
Color::Magenta => "5;13",
|
Color::Magenta => f.write_str("5;13"),
|
||||||
Color::DarkMagenta => "5;5",
|
Color::DarkMagenta => f.write_str("5;5"),
|
||||||
Color::Cyan => "5;14",
|
Color::Cyan => f.write_str("5;14"),
|
||||||
Color::DarkCyan => "5;6",
|
Color::DarkCyan => f.write_str("5;6"),
|
||||||
Color::White => "5;15",
|
Color::White => f.write_str("5;15"),
|
||||||
Color::Grey => "5;7",
|
Color::Grey => f.write_str("5;7"),
|
||||||
Color::Rgb { r, g, b } => {
|
Color::Rgb { r, g, b } => write!(f, "2;{};{};{}", r, g, b),
|
||||||
ansi_value.push_str(format!("2;{};{};{}", r, g, b).as_str());
|
Color::AnsiValue(val) => write!(f, "5;{}", val),
|
||||||
""
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
Color::AnsiValue(val) => {
|
|
||||||
ansi_value.push_str(format!("5;{}", val).as_str());
|
|
||||||
""
|
|
||||||
}
|
|
||||||
_ => "",
|
|
||||||
};
|
|
||||||
|
|
||||||
ansi_value.push_str(color_val);
|
|
||||||
ansi_value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,36 +85,36 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_fg_color() {
|
fn test_parse_fg_color() {
|
||||||
let colored = Colored::ForegroundColor(Color::Red);
|
let colored = Colored::ForegroundColor(Color::Red);
|
||||||
assert_eq!(Into::<String>::into(colored), "38;5;9");
|
assert_eq!(colored.to_string(), "38;5;9");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_bg_color() {
|
fn test_parse_bg_color() {
|
||||||
let colored = Colored::BackgroundColor(Color::Red);
|
let colored = Colored::BackgroundColor(Color::Red);
|
||||||
assert_eq!(Into::<String>::into(colored), "48;5;9");
|
assert_eq!(colored.to_string(), "48;5;9");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_reset_fg_color() {
|
fn test_parse_reset_fg_color() {
|
||||||
let colored = Colored::ForegroundColor(Color::Reset);
|
let colored = Colored::ForegroundColor(Color::Reset);
|
||||||
assert_eq!(Into::<String>::into(colored), "39");
|
assert_eq!(colored.to_string(), "39");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_reset_bg_color() {
|
fn test_parse_reset_bg_color() {
|
||||||
let colored = Colored::BackgroundColor(Color::Reset);
|
let colored = Colored::BackgroundColor(Color::Reset);
|
||||||
assert_eq!(Into::<String>::into(colored), "49");
|
assert_eq!(colored.to_string(), "49");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_fg_rgb_color() {
|
fn test_parse_fg_rgb_color() {
|
||||||
let colored = Colored::BackgroundColor(Color::Rgb { r: 1, g: 2, b: 3 });
|
let colored = Colored::BackgroundColor(Color::Rgb { r: 1, g: 2, b: 3 });
|
||||||
assert_eq!(Into::<String>::into(colored), "48;2;1;2;3");
|
assert_eq!(colored.to_string(), "48;2;1;2;3");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_fg_ansi_color() {
|
fn test_parse_fg_ansi_color() {
|
||||||
let colored = Colored::ForegroundColor(Color::AnsiValue(255));
|
let colored = Colored::ForegroundColor(Color::AnsiValue(255));
|
||||||
assert_eq!(Into::<String>::into(colored), "38;5;255");
|
assert_eq!(colored.to_string(), "38;5;255");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ macro_rules! def_color {
|
|||||||
$side: Some($color),
|
$side: Some($color),
|
||||||
..self.style
|
..self.style
|
||||||
},
|
},
|
||||||
self.content
|
self.content,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -28,7 +28,7 @@ macro_rules! def_str_color {
|
|||||||
$side: Some($color),
|
$side: Some($color),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
self
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -42,7 +42,7 @@ macro_rules! def_char_color {
|
|||||||
$side: Some($color),
|
$side: Some($color),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
self
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -56,10 +56,10 @@ macro_rules! def_str_attr {
|
|||||||
attributes: $attr.into(),
|
attributes: $attr.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
self
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! def_char_attr {
|
macro_rules! def_char_attr {
|
||||||
@ -70,8 +70,8 @@ macro_rules! def_char_attr {
|
|||||||
attributes: $attr.into(),
|
attributes: $attr.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
self
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user