pub struct Text(/* private fields */);Expand description
Sanitized, display-safe text.
Constructing a Text always goes through Text::sanitize (directly, or
indirectly via Deserialize), which strips control characters and
terminal escape sequences, resolves backspace-overstrike, expands tabs,
collapses whitespace runs, normalizes newlines (preserving paragraph
breaks), and truncates to MAX_TEXT_CHARS. Widgets and other consumers
may assume a Text is safe to place directly into a rendering surface.
Implementations§
Source§impl Text
impl Text
Sourcepub fn sanitize(raw: &str) -> Text
pub fn sanitize(raw: &str) -> Text
The only way to build a Text from raw, untrusted input.
Pipeline (see spec §4.1 and §13.3 for the adversarial cases this must survive):
- Strip ANSI/OSC/other terminal escape sequences.
- Resolve backspace-overstrike (
_\bX,X\bX, and any stray\b). - Strip remaining C0 control characters and DEL.
- Expand tabs to spaces at 8-column stops.
- Normalize line endings to
\n. - Unwrap hard-wrapped paragraphs: a single
\ninside a paragraph joins to a space (so a later re-wrap at the pane’s actual width produces clean lines instead of re-wrapping already-short, pre-broken lines raggedly);\n\nstays a paragraph break; indented/code-like lines and list items (-,*,1.) are never joined to a neighbor, preserving block structure. - Collapse runs of horizontal whitespace to a single space.
- Trim leading/trailing whitespace.
- Truncate to
MAX_TEXT_CHARScharacters, at a char boundary.
Sourcepub fn sanitize_markdown(raw: &str) -> Text
pub fn sanitize_markdown(raw: &str) -> Text
Like Text::sanitize, but for text known to originate as
markdown-flavored prose (carapace-spec’s description/
documentation fields, which use [label](uri) links — including
custom schemes like man:// and cmd:// — plus inline code,
**bold**, and *em*/_em_ markers).
This is a conservative, targeted normalizer, not a general markdown
parser: it recognizes exactly those four constructs and leaves
anything else untouched. In particular it does not touch [value]
usage-string brackets (no following (...)), and it requires
non-word characters immediately outside *em*/_em_ delimiters so
it doesn’t misfire on identifiers like GIT_DIR or globs.
Recognized markup is replaced with its inner text; the surrounding
URI/delimiters are discarded (plain-text fallback, since the detail
pane doesn’t yet render hyperlinks).
Sourcepub fn sanitize_preserving_layout(raw: &str) -> Text
pub fn sanitize_preserving_layout(raw: &str) -> Text
Like Text::sanitize, but for the raw-help display path (the
verbatim pane, t), whose entire job is showing a tool’s own bytes
as they arrived — not turning them into IR prose. Text::sanitize
is the wrong gate there: its steps 6-8 (unwrap hard-wrapped
paragraphs, collapse whitespace runs, trim leading/trailing
whitespace) are exactly what destroy column alignment, and column
alignment is the one thing a side-by-side “does this match the raw
pane’s ground truth” review depends on.
This still neutralizes terminal control sequences — the one thing the raw pane cannot safely pass through, since ANSI/OSC/DCS escapes, stray carriage returns, and other C0 controls could scramble the reader’s terminal or misrepresent what arrived — and nothing else:
- Strip ANSI/OSC/DCS escape sequences (shares [
strip_escapes] withText::sanitize— same hazard, same fix). - Strip remaining C0 control characters and DEL, including a
stray
\r— callers pass one already-line-split string at a time (see below), so any\rstill present did not terminate a line and is exactly the “carriage return that lies about what’s on screen” hazard, not useful structure. - Expand tabs to spaces at 8-column stops. This is a neutralization
too, not a formatting choice:
ratatuidoes not interpret\tas a tab stop the way a real terminal does (unicode-widthgives it zero display width), so a raw tab left in would misalign columns in the pane relative to what the reader’s own terminal shows for the same bytes — the opposite of this function’s purpose. - Truncate to
MAX_TEXT_CHARS, the same boundText::sanitizeapplies, so a pathological single line cannot blow up the pane.
Deliberately not applied: unwrapping, whitespace-collapsing, trimming, or paragraph-break normalization — indentation and internal column alignment are preserved exactly as fetched, and blank lines are whatever the caller’s own line-splitting already produced.
Only [mandible-extract’s help_text::raw_help* functions] call
this; every other consumer of a --help probe keeps going through
Text::sanitize unchanged — this is an additional path for
display, not a redefinition of the existing one.
Sourcepub fn single_line(&self) -> String
pub fn single_line(&self) -> String
Collapse to a single display line (paragraph breaks and internal newlines become a single space), for contexts like tree rows that have no room for multi-line text. The tree pane is expected to call this at render time rather than store a second copy of the text.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Text
impl<'de> Deserialize<'de> for Text
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserialization re-runs Text::sanitize rather than trusting the
stored bytes verbatim. This keeps the invariant airtight even when a
Text is round-tripped through the on-disk cache (spec §11): a
tampered or corrupted cache file cannot smuggle unsanitized bytes
back into the IR. sanitize is idempotent, so this costs nothing
extra for cache entries that were already clean.
impl Eq for Text
impl StructuralPartialEq for Text
Auto Trait Implementations§
impl Freeze for Text
impl RefUnwindSafe for Text
impl Send for Text
impl Sync for Text
impl Unpin for Text
impl UnsafeUnpin for Text
impl UnwindSafe for Text
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.