textutil

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: AGPL-3.0 Imports: 1 Imported by: 0

Documentation

Overview

Package textutil provides small, dependency-free string-safety primitives shared by packages that must not depend on each other: rune-safe byte-cap truncation (jschema, delivery) and control-byte detection (workflows/controller, workflows/compiler). It also provides ASCII-folded containment (ContainsFold). Each importer needs the exact same check; this leaf package holds the one implementation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContainsFold

func ContainsFold(s, substr string) bool

ContainsFold reports whether s contains substr when only ASCII letters fold: 'A'-'Z' matches 'a'-'z' and 'a'-'z' matches 'A'-'Z'. Every other byte, including non-ASCII runes and malformed UTF-8, compares exactly and never folds. An empty substr is contained in every string. The scan uses a byte window of length len(substr) over s and is O(len(s)*len(substr)) in the worst case.

func HasControlByte

func HasControlByte(s string) bool

HasControlByte reports whether s contains a C0 control byte (0x00-0x1F) or DEL (0x7F). Callers that build an identity or digest by concatenating untrusted strings with a byte-level separator use this to reject a value that could smuggle that separator and collide two different identities.

func TruncateEllipsis

func TruncateEllipsis(s string, maxBytes int) string

TruncateEllipsis truncates s to a byte budget and appends the ellipsis rune "…" (U+2026, 3 bytes) when truncation happens and the budget can fit the marker.

When len(s) <= maxBytes, it returns s unchanged with no marker. When maxBytes <= 0, it returns "". When maxBytes < 3, the marker cannot fit, so it falls back to TruncateRuneSafe(s, maxBytes) with no marker. Otherwise it appends "…" to the longest prefix of s that fits maxBytes-3 bytes on a UTF-8 rune boundary. The result never exceeds maxBytes. For valid UTF-8 input, the result is valid UTF-8.

func TruncateMiddle

func TruncateMiddle(s string, maxLen int) string

TruncateMiddle shortens s to at most maxLen runes by keeping a rune-safe prefix and suffix and inserting one ASCII "..." marker between them. maxLen counts runes via utf8.RuneCountInString, not bytes.

When the rune count of s is at most maxLen, it returns s unchanged with no marker. When maxLen <= 0, it returns "". When maxLen < 3, the marker cannot fit, so it returns the first maxLen runes with no marker. Otherwise it splits the remaining maxLen-3 runes evenly: the prefix gets ceil((maxLen-3)/2) runes and the suffix gets the rest.

The result never exceeds maxLen runes and never splits a rune. For valid UTF-8 input, the result is valid UTF-8.

func TruncateRuneSafe

func TruncateRuneSafe(s string, maxBytes int) string

TruncateRuneSafe returns the longest prefix of s that is at most maxBytes bytes and ends on a UTF-8 rune boundary.

When len(s) <= maxBytes, it returns s unchanged. When maxBytes <= 0, it returns "". A cut inside a rune backs off to the previous rune start, so the result is always valid UTF-8 for valid UTF-8 input.

func TruncateTail

func TruncateTail(s string, maxBytes int) string

TruncateTail returns the longest suffix of s that is at most maxBytes bytes and starts on a UTF-8 rune boundary.

When len(s) <= maxBytes, it returns s unchanged. When maxBytes <= 0, it returns "". Error chains read wrapper first and root cause last, so the tail preserves the root cause for diagnostics.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL