ctoolbox/formats/eite/encoding/
pack32.rs1use anyhow::{Result, anyhow, bail};
2
3use crate::formats::wtf8::{
4 decode_wtf8_single, encode_wtf8_single, is_unpackable_wtf8,
5};
6
7pub fn pack32(value: u32) -> Result<Vec<u8>> {
14 encode_wtf8_single(value)
15}
16
17pub fn unpack32(bytes: &[u8]) -> Result<u32> {
24 let (cp, used) =
25 decode_wtf8_single(bytes).map_err(|e| anyhow!("unpack32: {e}"))?;
26 if used != bytes.len() {
27 bail!(
28 "unpack32: input contains extra bytes (decoded {} used {}, total {}, input {:?})",
29 cp,
30 used,
31 bytes.len(),
32 bytes
33 );
34 }
35 Ok(cp)
36}
37
38pub fn is_pack32_char(bytes: &[u8]) -> bool {
43 is_unpackable_wtf8(bytes)
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[crate::ctb_test]
51 fn test_pack32_roundtrip_basic() {
52 let bytes = pack32(0x41).unwrap();
54 assert!(is_pack32_char(&bytes));
55 let cp = unpack32(&bytes).unwrap();
56 assert_eq!(cp, 0x41);
57
58 let smile = 0x263A;
60 let bytes2 = pack32(smile).unwrap();
61 assert!(is_pack32_char(&bytes2));
62 let cp2 = unpack32(&bytes2).unwrap();
63 assert_eq!(cp2, smile);
64 }
65
66 #[crate::ctb_test]
67 fn test_pack32_surrogate_wtf8() {
68 let hi = 0xD83D;
70 let bytes = pack32(hi).unwrap();
71 assert!(is_pack32_char(&bytes));
72 let round = unpack32(&bytes).unwrap();
73 assert_eq!(round, hi);
74 }
75
76 #[crate::ctb_test]
77 fn test_pack32_round_trip() {
78 for &val in &[0, 10, 100, 1000, 10_000] {
79 let packed = pack32(val).unwrap();
80 let unpacked = unpack32(&packed).expect("unpack32 failed");
81 assert_eq!(val, unpacked, "pack32/unpack32 mismatch for {}", val);
82 }
83 }
84}