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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Minecraft text formatting utilities.
//!
//! Minecraft uses `§` (section sign, U+00A7) followed by a single character
//! to encode colours and text styles in MOTDs and other strings. These helpers
//! strip those codes and provide Unicode-safe string truncation.
//!
//! Both functions are re-exported from the crate root via
//! [`rust_mc_status::strip_formatting`](crate::strip_formatting) and
//! [`rust_mc_status::truncate_str`](crate::truncate_str).
//!
//! # Colour / formatting code reference
//!
//! | Code | Meaning | Code | Meaning |
//! |------|---------|------|---------|
//! | `§0`–`§9` | Colours (black–blue) | `§a`–`§f` | Colours (green–white) |
//! | `§k` | Obfuscated | `§l` | Bold |
//! | `§m` | Strikethrough | `§n` | Underline |
//! | `§o` | Italic | `§r` | Reset |
/// Strip Minecraft colour and formatting codes (`§X`) from a string.
///
/// Removes every `§` character and the single character that follows it,
/// then collapses all remaining whitespace runs (spaces, tabs, newlines) into
/// single spaces and trims the result.
///
/// # Example
///
/// ```
/// use rust_mc_status::strip_formatting;
///
/// // Hypixel MOTD with colours, newline, and bold
/// let raw = "§f §aHypixel Network §c[1.8/1.21]\n§b§lEASTER EVENT";
/// assert_eq!(strip_formatting(raw), "Hypixel Network [1.8/1.21] EASTER EVENT");
///
/// // Plain text passes through unchanged (minus any extra whitespace)
/// assert_eq!(strip_formatting("Hello World"), "Hello World");
///
/// // Only formatting codes → empty string
/// assert_eq!(strip_formatting("§a§b§l"), "");
/// ```
/// Truncate a string to at most `max_chars` Unicode scalar values.
///
/// Unlike a raw byte slice (`&s[..n]`), this function always cuts on a valid
/// character boundary — safe for multibyte characters such as Cyrillic, CJK,
/// and emoji. Returns the original string unchanged if it is shorter than
/// `max_chars`.
///
/// # Example
///
/// ```
/// use rust_mc_status::truncate_str;
///
/// // ASCII
/// assert_eq!(truncate_str("Hello, world!", 5), "Hello");
///
/// // Cyrillic (2 bytes per char — raw byte slicing would panic or corrupt)
/// assert_eq!(truncate_str("Привет, мир!", 7), "Привет,");
///
/// // Emoji (4 bytes per char)
/// assert_eq!(truncate_str("hello 🌍 world", 7), "hello 🌍");
///
/// // Shorter than limit — returned unchanged
/// assert_eq!(truncate_str("hi", 100), "hi");
///
/// // Limit 0 — always empty
/// assert_eq!(truncate_str("hello", 0), "");
/// ```