Permalink
Browse files

Support painting bytestrings

Applications working with text in unknown or non-UTF-8 character sets
need to handle that text as opaque [u8] bytestrings.  For example, git
diffs from git2-rs provide the diff text as [u8] bytestrings, because
the files diffed might not use UTF-8.

Add support for painting [u8] bytestrings, producing a new
ANSIByteString type.  Add an ANSIByteStrings type to print many
ANSIByteString values with minimal escape sequences.

To avoid duplicating code for str and [u8], introduce generic versions
of ANSIString and ANSIStrings, with the specific versions for str and
[u8] as type aliases.  Also introduce a private trait AnyWrite to
abstract code that works with either fmt::Write and io::Write.

This implementation provides full source compatibility with code written
for previous versions of ansi_term.  All the existing tests pass
unmodified.  Nonetheless, this should likely bump the version to 0.9.0,
because the introduction of generic types may potentially affect type
inference.

Extend the testsuite to run all the tests on ANSIByteString, as well.
  • Loading branch information...
joshtriplett committed Jul 28, 2016
1 parent da69fa2 commit a0da28ad91c15cb90d85b79048b6a3878f4386e1
Showing with 209 additions and 59 deletions.
  1. +26 −0 README.md
  2. +183 −59 src/lib.rs
View
@@ -141,3 +141,29 @@ Firstly, the `paint` method can take *either* an owned `String` or a borrowed `&
Internally, an `ANSIString` holds a copy-on-write (`Cow`) string value to deal with both owned and borrowed strings at the same time.
This is used here to display a `String`, the result of the `format!` call, using the same mechanism as some statically-available `&str` slices.
Secondly, that the `ANSIStrings` value works in the same way as its singular counterpart, with a `Display` implementation that only performs the formatting when required.
## Byte strings
This library also supports formatting `[u8]` byte strings; this supports
applications working with text in an unknown encoding. `Style` and
`Color` support painting `[u8]` values, resulting in an `ANSIByteString`.
This type does not implement `Display`, as it may not contain UTF-8, but
it does provide a method `write_to` to write the result to any
`io::Write`:
```rust
use ansi_term::Colour::Green;
Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap();
```
Similarly, the type `ANSIByteStrings` supports writing a list of
`ANSIByteString` values with minimal escape sequences:
```rust
use ansi_term::Colour::Green;
use ansi_term::ANSIByteStrings;
ANSIByteStrings(&[
Green.paint("user data 1\n".as_bytes()),
Green.bold().paint("user data 2\n".as_bytes()),
]).write_to(&mut std::io::stdout()).unwrap();
```
Oops, something went wrong.

0 comments on commit a0da28a

Please sign in to comment.