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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! String encode codecs for KLV data
//!
//! Provides encoders for converting Rust string types and numeric values
//! into raw byte slices suitable for KLV value fields. All encoders return
//! `Vec<u8>` and are compatible with the `#[klv(enc = ...)]` derive macro attribute.
//!
//! Includes:
//! * UTF-8 encoder (`from_string_utf8`)
//! * UTF-16 encoders for little-endian and big-endian byte order
//! * ASCII string encoder (`from_string_ascii`)
//! * ASCII-encoded value encoders: base-10 text for all integer and float
//! primitive types, and base-16 hex text (`hex_*`) for unsigned integers
//!
//! The decode counterparts live in [`crate::codecs::string::dec`].
//!
//! Author: aav
/// Encodes a string as UTF-8 bytes.
///
/// **Roundtrip warning**: If the original data was decoded with [`to_string_utf8`](crate::codecs::string::dec::to_string_utf8)
/// (which uses `from_utf8_lossy`), invalid UTF-8 bytes are replaced with U+FFFD
/// during decode. Re-encoding produces different (longer) bytes. Use
/// [`to_string_utf8_strict`](crate::codecs::string::dec::to_string_utf8_strict) on the decode side for lossless roundtrip.
///
/// Note: encoding from `&str` is inherently strict (Rust `&str` is always valid
/// UTF-8), so no separate `from_string_utf8_strict` encoder is needed.
///
/// # Example
///
/// ```
/// use tinyklv::codecs::string::enc::from_string_utf8;
///
/// let encoded = from_string_utf8("AF-101");
/// assert_eq!(encoded, vec![0x41, 0x46, 0x2D, 0x31, 0x30, 0x31]);
/// ```
/// Encodes a string as UTF-16 little-endian bytes.
///
/// **Endianness warning**: Using the wrong endianness variant will silently
/// produce corrupted string data. Verify the endianness of your KLV stream
/// before selecting a variant.
///
/// # Example
///
/// ```
/// use tinyklv::codecs::string::enc::from_string_utf16_le;
///
/// let encoded = from_string_utf16_le("AB");
/// // 'A' = 0x0041 LE -> [0x41, 0x00], 'B' = 0x0042 LE -> [0x42, 0x00]
/// assert_eq!(encoded, vec![0x41, 0x00, 0x42, 0x00]);
///
/// // emoji U+1F600 produces a surrogate pair
/// let emoji = from_string_utf16_le("\u{1F600}");
/// assert_eq!(emoji.len(), 4); // 2 code units × 2 bytes
/// ```
/// Encodes a string as UTF-16 big-endian bytes.
///
/// **Endianness warning**: Using the wrong endianness variant will silently
/// produce corrupted string data. Verify the endianness of your KLV stream
/// before selecting a variant.
///
/// # Example
///
/// ```
/// use tinyklv::codecs::string::enc::from_string_utf16_be;
///
/// let encoded = from_string_utf16_be("AB");
/// // 'A' = 0x0041 BE -> [0x00, 0x41], 'B' = 0x0042 BE -> [0x00, 0x42]
/// assert_eq!(encoded, vec![0x00, 0x41, 0x00, 0x42]);
/// ```
/// Equivalent to [`from_string_utf8`] for ASCII input.
///
/// Both exist for API symmetry with the decode side, which has separate
/// `to_string_utf8` and `to_string_ascii` functions.
///
/// # Example
///
/// ```
/// use tinyklv::codecs::string::enc::from_string_ascii;
///
/// let encoded = from_string_ascii("HELLO");
/// assert_eq!(encoded, b"HELLO".to_vec());
/// ```
/// Generates a base-10 integer/float encoder
/// Generates a base-16 unsigned integer encoder
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_display!;
ascii_hex!;
ascii_hex!;
ascii_hex!;
ascii_hex!;
ascii_hex!;