Skip to content

Commit

Permalink
make minor code and comment tweaks, including to address outstanding …
Browse files Browse the repository at this point in the history
…CI failures; also add more tests
  • Loading branch information
apparebit committed Mar 6, 2025
1 parent 5c98bc0 commit 9187d67
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 28 deletions.
11 changes: 6 additions & 5 deletions crates/prettypretty/src/style/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,18 @@ impl Layer {
)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Fidelity {
/// Plain text, no ANSI escape codes
/// Plain text, no ANSI escape codes.
Plain,
/// ANSI escape codes but no colors
/// ANSI escape codes but no colors.
NoColor,
/// ANSI and default colors only
/// ANSI and default colors only.
Ansi,
/// 8-bit indexed colors including ANSI and default colors
/// 8-bit indexed colors including ANSI and default colors.
EightBit,
/// 24-bit RGB color.
TwentyFourBit,
/// High-resolution colors in arbitrary color spaces
/// High-resolution colors in arbitrary color spaces, an aspirational
/// terminal feature.
HiRes,
}

Expand Down
40 changes: 30 additions & 10 deletions crates/prettypretty/src/termco.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,13 +1290,13 @@ impl Colorant {
layer: Layer,
) -> Result<impl core::fmt::Display + use<'_>, HiResColorantError> {
if matches!(*self, Self::HiRes(_)) {
Err(HiResColorantError)
} else {
Ok(LayeredColorant {
layer,
colorant: self,
})
return Err(HiResColorantError);
}

Ok(LayeredColorant {
layer,
colorant: self,
})
}
}

Expand Down Expand Up @@ -1446,11 +1446,11 @@ impl TryFrom<Colorant> for Color {

fn try_from(value: Colorant) -> Result<Self, Self::Error> {
if let Colorant::HiRes(c) = value {
Ok(c)
} else {
let [r, g, b] = value.try_into()?;
Ok(Color::from_24bit(r, g, b))
return Ok(c);
}

let [r, g, b] = value.try_into()?;
Ok(Color::from_24bit(r, g, b))
}
}

Expand All @@ -1470,6 +1470,26 @@ impl core::fmt::Display for LayeredColorant<'_> {
#[cfg(test)]
mod test {
use super::{AnsiColor, Colorant, EmbeddedRgb, GrayGradient, OutOfBoundsError, Rgb};
use crate::Color;

#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
#[test]
fn test_size() {
assert_eq!(std::mem::size_of::<AnsiColor>(), 1);
assert_eq!(std::mem::align_of::<AnsiColor>(), 1);

assert_eq!(std::mem::size_of::<EmbeddedRgb>(), 3);
assert_eq!(std::mem::align_of::<EmbeddedRgb>(), 1);

assert_eq!(std::mem::size_of::<Rgb>(), 3);
assert_eq!(std::mem::align_of::<Rgb>(), 1);

assert_eq!(std::mem::size_of::<Color>(), 32);
assert_eq!(std::mem::align_of::<Color>(), 8);

assert_eq!(std::mem::size_of::<Colorant>(), 32);
assert_eq!(std::mem::align_of::<Colorant>(), 8);
}

#[test]
fn test_conversion() -> Result<(), OutOfBoundsError> {
Expand Down
10 changes: 6 additions & 4 deletions crates/prettypretty/src/trans/translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,10 @@ impl Translator {
}
Fidelity::TwentyFourBit => {
if let Colorant::HiRes(ref hires_color) = *colorant {
Some(Colorant::Rgb(hires_color.into()))
} else {
Some(colorant.clone())
return Some(Colorant::Rgb(hires_color.into()));
}

Some(colorant.clone())
}
Fidelity::HiRes => Some(colorant.clone()),
}
Expand Down Expand Up @@ -652,7 +652,9 @@ impl Translator {
pub fn resolve<C: Into<Colorant>>(&self, color: C) -> Color {
let color = color.into();
if matches!(color, Colorant::Default()) {
panic!("Translator::resolve() cannot process the default colorant; use Translator::resolve_all() instead.")
panic!(
"Translator::resolve() cannot process the default colorant; use Translator::resolve_all() instead."
)
}
self.resolve_all(color, Layer::Foreground)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/prettytty/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ impl<Q: Query + ?Sized> Query for Box<Q> {
// ------------------------------------------------------------------------------------------------

/// A text or control sequence token.
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Eq)]
pub enum Token<'t> {
/// One or more UTF-8 characters excluding C0 and C1 controls.
Text(&'t [u8]),
Expand Down
5 changes: 4 additions & 1 deletion crates/prettytty/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! This module provides a number of straight-forward struct and enum types that
//! implement the [`Command`] trait and, where needed, also the [`Sgr`] and
//! [`Query`] traits. Organized by topic, this library covers the following 84
//! [`Query`] traits. Organized by topic, this library covers the following 86
//! commands:
//!
//! * Terminal identification:
Expand All @@ -19,6 +19,7 @@
//! * [`ScrollUp`], [`ScrollDown`], [`DynScrollUp`], and [`DynScrollDown`]
//! * [`SetScrollRegion`] and [`DynSetScrollRegion`]
//! * [`ResetScrollRegion`]
//! * [`EnableAutowrap`] and [`DisableAutowrap`]
//! * Cursor management:
//! * [`SetCursor::Default`], [`SetCursor::BlinkingBlock`],
//! [`SetCursor::SteadyBlock`], [`SetCursor::BlinkingUnderscore`],
Expand Down Expand Up @@ -370,6 +371,8 @@ define_cmd_1!(ScrollDown<ROWS: u16>, DynScrollDown, "\x1b[", "S");

define_cmd_2!(SetScrollRegion<TOP: u16, BOTTOM: u16>, DynSetScrollRegion, "\x1b[", "r");
define_unit_command!(ResetScrollRegion, "\x1b[r");
define_unit_command!(EnableAutowrap, "\x1b[?7h");
define_unit_command!(DisableAutowrap, "\x1b[?7l");

// --------------------------------- Cursor Management ---------------------------------

Expand Down
2 changes: 1 addition & 1 deletion crates/prettytty/src/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ pub struct Input<'a> {
pub scanner: MutexGuard<'a, Scanner<Box<dyn Read + Send>>>,
}

impl<'a> Input<'a> {
impl Input<'_> {
/// Determine whether the input has bytes buffered.
#[must_use = "the only reason to invoke method is to access the returned value"]
pub fn is_readable(&self) -> bool {
Expand Down
3 changes: 2 additions & 1 deletion crates/prettytty/src/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ mod test {
fn test_events() {
let input = [
b"a \xe2\x9c\xb6 \x1b[+=+@ \x1bOR \xe2x \x07 ".as_slice(),
b"\x1b[31m \x1b[123$$4<=>m \xe2\x81\x82".as_slice(),
b"\x1b[31m \x1b[123$$4<=>m \xe2\x81\x82\x1b[38:5:90m".as_slice(),
]
.concat();
let input = input.as_slice();
Expand All @@ -385,6 +385,7 @@ mod test {
Ok(Token::Text(b" ".as_slice())),
Err(ErrorKind::MalformedSequence.into()),
Ok(Token::Text(b" \xe2\x81\x82".as_slice())),
Ok(Token::Sequence(Control::CSI, b"38:5:90m".as_slice())),
];

let mut scanner = Scanner::with_options(&Options::default(), input);
Expand Down
5 changes: 3 additions & 2 deletions crates/prettytty/src/scan/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,9 @@ const fn csi_param(byte: u8) -> (State, Action, Option<Control>) {

match byte {
0x20..=0x2f => (CsiIntermediate, RetainByte, None),
0x30..=0x39 | 0x3b => (CsiParam, RetainByte, None),
0x3a | 0x3c..=0x3f => (CsiIgnore, IgnoreByte, None),
// The original state machine transitions to CsiIgnore on 0x3a (:) and
// 0x3c..=0x3f (<=>?), but those bytes are used in IRL escape sequences.
0x30..=0x3f => (CsiParam, RetainByte, None),
0x40..=0x7e => (Ground, Dispatch, None),
_ => otherwise(byte, CsiParam),
}
Expand Down
9 changes: 6 additions & 3 deletions crates/prettytty/src/scan/utf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ pub(super) fn read_utf8(bytes: &[u8]) -> core::result::Result<(char, usize), usi

// scan_utf8_length() inspects all bytes of a valid UTF-8 character.
let length = scan_utf8_length(bytes)?;
assert!(length <= bytes.len());
assert!(
length <= bytes.len(),
"buffer does not contain sufficient bytes despite UTF-8 validation"
);

let mut codepoint = (bytes[0] & (0x7f >> length)) as u32;
for index in 1..length {
codepoint = (codepoint << 6) | (bytes[index] & CONTINUATION_MASK) as u32;
for byte in bytes.iter().take(length).skip(1) {
codepoint = (codepoint << 6) | (byte & CONTINUATION_MASK) as u32;
}

// SAFETY: scan_utf8_length() validated length bytes as UTF-8, above loop
Expand Down

0 comments on commit 9187d67

Please sign in to comment.