Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a feature flag for tty support #47

Merged
merged 2 commits into from
Aug 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,27 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
wasm:
name: Check wasm32-wasi support with ${{ matrix.toolchain }} toolchain
runs-on: ubuntu-latest
strategy:
matrix:
toolchain: [stable, nightly]

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
target: wasm32-wasi
toolchain: ${{ matrix.toolchain }}
override: true

- name: cargo build
uses: actions-rs/cargo@v1
with:
command: build
args: --release --no-default-features --target wasm32-wasi
15 changes: 14 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ edition = "2018"
maintenance = { status = "actively-developed" }

[dependencies]
crossterm = "0.20"
crossterm = {version = "0.20", optional = true }
strum = "0.21"
strum_macros = "0.21"
unicode-width = "0.1"


[features]
default = ["tty"]
tty = ["crossterm"]

[dev-dependencies]
pretty_assertions = "0.7"
doc-comment = "0.3"
Expand All @@ -29,3 +34,11 @@ criterion = "0.3"
[[bench]]
name = "build_tables"
harness = false

[[example]]
name = "no_tty"
path = "examples/readme_table_no_tty.rs"

[[example]]
name = "readme_table"
path = "examples/readme_table.rs"
27 changes: 27 additions & 0 deletions benches/build_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use comfy_table::Width::*;
use comfy_table::*;

/// Build the readme table
#[cfg(feature = "tty")]
fn build_readme_table() {
let mut table = Table::new();
table.load_preset(UTF8_FULL)
Expand Down Expand Up @@ -37,6 +38,32 @@ fn build_readme_table() {
let _ = table.lines();
}

#[cfg(not(feature = "tty"))]
fn build_readme_table() {
let mut table = Table::new();
table.load_preset(UTF8_FULL)
.set_content_arrangement(ContentArrangement::Dynamic)
.set_table_width(80)
.set_header(vec![
Cell::new("Header1"),
Cell::new("Header2"),
Cell::new("Header3"),
])
.add_row(vec![
Cell::new("This is a bold text"),
Cell::new("This is a green text"),
Cell::new("This one has black background"),
])
.add_row(vec![
Cell::new("Blinky boi"),
Cell::new("This table's content is dynamically arranged. The table is exactly 80 characters wide.\nHere comes a reallylongwordthatshoulddynamicallywrap"),
Cell::new("COMBINE ALL THE THINGS"),
]);

// Build the table.
let _ = table.lines();
}

/// Create a dynamic 10x10 Table with width 400 and unevenly distributed content.
/// On top of that, most of the columns have some kind of constraint.
fn build_huge_table() {
Expand Down
29 changes: 29 additions & 0 deletions examples/readme_table_no_tty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use comfy_table::presets::UTF8_FULL;
use comfy_table::*;

// This example works even with the `tty` feature disabled
// You can try it out with `cargo run --example no_tty --no-default-features`

fn main() {
let mut table = Table::new();
table.load_preset(UTF8_FULL)
.set_content_arrangement(ContentArrangement::Dynamic)
.set_table_width(80)
.set_header(vec![
Cell::new("Header1"),
Cell::new("Header2"),
Cell::new("Header3"),
])
.add_row(vec![
Cell::new("No bold text without tty"),
Cell::new("No colored text without tty"),
Cell::new("No custom background without tty"),
])
.add_row(vec![
Cell::new("Blinky boi"),
Cell::new("This table's content is dynamically arranged. The table is exactly 80 characters wide.\nHere comes a reallylongwordthatshoulddynamicallywrap"),
Cell::new("Done"),
]);

println!("{}", table);
}
11 changes: 11 additions & 0 deletions src/cell.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "tty")]
use crossterm::style::{Attribute, Color};

use crate::style::CellAlignment;
Expand All @@ -13,8 +14,11 @@ pub struct Cell {
/// The default is ` `.
pub(crate) delimiter: Option<char>,
pub(crate) alignment: Option<CellAlignment>,
#[cfg(feature = "tty")]
pub(crate) fg: Option<Color>,
#[cfg(feature = "tty")]
pub(crate) bg: Option<Color>,
#[cfg(feature = "tty")]
pub(crate) attributes: Vec<Attribute>,
}

Expand All @@ -29,8 +33,11 @@ impl Cell {
.collect(),
delimiter: None,
alignment: None,
#[cfg(feature = "tty")]
fg: None,
#[cfg(feature = "tty")]
bg: None,
#[cfg(feature = "tty")]
attributes: Vec::new(),
}
}
Expand Down Expand Up @@ -77,6 +84,7 @@ impl Cell {
/// let mut cell = Cell::new("Some content")
/// .fg(Color::Red);
/// ```
#[cfg(feature = "tty")]
pub fn fg(mut self, color: Color) -> Self {
self.fg = Some(color);

Expand All @@ -94,6 +102,7 @@ impl Cell {
/// let mut cell = Cell::new("Some content")
/// .bg(Color::Red);
/// ```
#[cfg(feature = "tty")]
pub fn bg(mut self, color: Color) -> Self {
self.bg = Some(color);

Expand All @@ -112,13 +121,15 @@ impl Cell {
/// let mut cell = Cell::new("Some content")
/// .add_attribute(Attribute::Bold);
/// ```
#[cfg(feature = "tty")]
pub fn add_attribute(mut self, attribute: Attribute) -> Self {
self.attributes.push(attribute);

self
}

/// Same as add_attribute, but you can pass a vector of [Attributes](Attribute)
#[cfg(feature = "tty")]
pub fn add_attributes(mut self, mut attribute: Vec<Attribute>) -> Self {
self.attributes.append(&mut attribute);

Expand Down
2 changes: 2 additions & 0 deletions src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub use column::{ColumnConstraint, Width};
pub use table::{ContentArrangement, TableComponent};

/// Attributes used for styling cell content. Reexport of crossterm's [Attributes](crossterm::style::Attribute) enum.
#[cfg(feature = "tty")]
pub use crossterm::style::Attribute;
/// Colors used for styling cell content. Reexport of crossterm's [Color](crossterm::style::Color) enum.
#[cfg(feature = "tty")]
pub use crossterm::style::Color;
19 changes: 19 additions & 0 deletions src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use std::fmt;
use std::iter::IntoIterator;
use std::slice::{Iter, IterMut};

#[cfg(feature = "tty")]
use crossterm::terminal::size;
#[cfg(feature = "tty")]
use crossterm::tty::IsTty;
use strum::IntoEnumIterator;

Expand Down Expand Up @@ -137,6 +139,7 @@ impl Table {
///
/// If neither is not possible, `None` will be returned.\
/// This implies that both the [Dynamic](ContentArrangement::Dynamic) mode and the [Percentage](crate::style::ColumnConstraint::Percentage) constraint won't work.
#[cfg(feature = "tty")]
pub fn get_table_width(&self) -> Option<u16> {
if let Some(width) = self.table_width {
Some(width)
Expand All @@ -151,6 +154,15 @@ impl Table {
}
}

#[cfg(not(feature = "tty"))]
pub fn get_table_width(&self) -> Option<u16> {
if let Some(width) = self.table_width {
Some(width)
} else {
None
}
}

/// Specify how Comfy Table should arrange the content in your table.
///
/// ```
Expand Down Expand Up @@ -196,6 +208,7 @@ impl Table {
///
/// This function respects the [Table::force_no_tty] function.\
/// Otherwise we try to determine, if we are on a tty.
#[cfg(feature = "tty")]
pub fn is_tty(&self) -> bool {
if self.no_tty {
return false;
Expand All @@ -204,6 +217,11 @@ impl Table {
::std::io::stdout().is_tty()
}

#[cfg(not(feature = "tty"))]
pub fn is_tty(&self) -> bool {
false
}

/// Enforce terminal styling.
///
/// Only useful if you forcefully disabled tty, but still want those fancy terminal styles.
Expand All @@ -215,6 +233,7 @@ impl Table {
/// table.force_no_tty()
/// .enforce_styling();
/// ```
#[cfg(feature = "tty")]
pub fn enforce_styling(&mut self) -> &mut Self {
self.enforce_styling = true;

Expand Down
22 changes: 19 additions & 3 deletions src/utils/formatting/content_format.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "tty")]
use crossterm::style::{style, Stylize};
use unicode_width::UnicodeWidthStr;

Expand Down Expand Up @@ -123,12 +124,26 @@ pub fn format_row(
.iter()
.map(|line| align_line(line.to_string(), info, cell));

// Style the cell if necessary.
// Apply tty styling for this cell.
#[cfg(feature = "tty")]
let cell_lines = apply_tty_styling(table, cell, cell_lines).into_iter();

temp_row_content.push(cell_lines.collect());
}

#[cfg(feature = "tty")]
/// A small wrapper around the top-level cell styling logic. It's only used to have a clear
/// separation of our tty styling logic for the `tty` feature flag.
fn apply_tty_styling(
table: &Table,
cell: &Cell,
cell_lines: impl Iterator<Item = String>,
) -> Vec<String> {
if table.should_style() {
let cell_lines = cell_lines.map(|line| style_line(line, cell));
temp_row_content.push(cell_lines.collect());
cell_lines.collect()
} else {
temp_row_content.push(cell_lines.collect());
cell_lines.collect()
}
}

Expand Down Expand Up @@ -223,6 +238,7 @@ fn pad_line(line: String, info: &ColumnDisplayInfo) -> String {
padded_line
}

#[cfg(feature = "tty")]
fn style_line(line: String, cell: &Cell) -> String {
let mut content = style(line);

Expand Down
2 changes: 2 additions & 0 deletions tests/all/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod alignment_test;
#[cfg(feature = "tty")]
mod combined_test;
mod constraints_test;
mod content_arrangement_test;
Expand All @@ -9,5 +10,6 @@ mod padding_test;
mod presets_test;
mod property_test;
mod simple_test;
#[cfg(feature = "tty")]
mod styling_test;
mod utf_8_characters;