1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//! Shared utility functions for safe string manipulation.
//!
//! All functions are UTF-8-safe — they never split multi-byte characters, and the
//! newline variant stops at line boundaries for log-preview use cases.
/// Truncate `s` to at most `max` bytes, landing on a valid UTF-8 character boundary.
///
/// Unlike naive `&s[..max]` this avoids splitting multi-byte characters (emoji, CJK).
///
/// # Arguments
///
/// * `s` - The string slice to truncate.
/// * `max` - Maximum byte length. If `max` exceeds `s.len()`, the entire string is returned unchanged.
///
/// # Returns
///
/// A subslice of `s` that is at most `max` bytes long and ends on a valid UTF-8 character boundary.
///
/// # Panics
///
/// Does not panic — uses [`str::floor_char_boundary`] internally which clamps safely.
/// Like [`truncate_utf8`] but also stops at the first newline if it appears before `max`.
/// Useful for log previews where long multi-line output should show only the first line.
///
/// # Arguments
///
/// * `s` - The string slice to truncate.
/// * `max` - Maximum byte length of the returned slice (before newline clipping).
///
/// # Returns
///
/// A subslice of `s` that is at most `max` bytes, ends on a valid UTF-8 boundary, and does not
/// cross a newline (`\n` or `\r`). If no newline exists within `max` bytes, behaves identically
/// to [`truncate_utf8`].