lua_types/string.rs
1//! `LuaString` — Lua's byte-string (NOT UTF-8). PORT_STRATEGY §3.3.
2//!
3//! Phase A-C: a simple `Rc<[u8]>`-backed struct with a short/long flag.
4//! Phase D may revisit for interning + content-hash equality.
5
6#[derive(Debug, Clone)]
7pub struct LuaString {
8 bytes: std::rc::Rc<[u8]>,
9 is_short: bool,
10 hash: u32,
11}
12
13impl LuaString {
14 pub fn from_bytes(b: Vec<u8>) -> Self {
15 let is_short = b.len() <= 40;
16 let hash = Self::hash_bytes(&b, 0);
17 LuaString {
18 bytes: b.into(),
19 is_short,
20 hash,
21 }
22 }
23
24 pub fn placeholder() -> Self {
25 Self::from_bytes(Vec::new())
26 }
27
28 pub fn as_bytes(&self) -> &[u8] {
29 &self.bytes
30 }
31 pub fn len(&self) -> usize {
32 self.bytes.len()
33 }
34 pub fn is_empty(&self) -> bool {
35 self.bytes.is_empty()
36 }
37 pub fn is_short(&self) -> bool {
38 self.is_short
39 }
40 pub fn is_long(&self) -> bool {
41 !self.is_short
42 }
43 pub fn hash(&self) -> u32 {
44 self.hash
45 }
46 pub fn buffer_bytes(&self) -> usize {
47 self.bytes.len() + 2 * std::mem::size_of::<usize>()
48 }
49
50 pub fn is_reserved_word(&self) -> bool {
51 // TODO(port): proper reserved-word check via lexer's token enum.
52 false
53 }
54
55 pub fn hash_bytes(bytes: &[u8], seed: u32) -> u32 {
56 // Stub WyHash. Real impl ports bun_wyhash. Stable for now so
57 // intern-table equality works.
58 let mut h: u32 = seed.wrapping_add(0x9e3779b9);
59 for &b in bytes {
60 h = h.wrapping_mul(31).wrapping_add(b as u32);
61 }
62 h
63 }
64
65 pub fn hash_long(&mut self) -> u32 {
66 self.hash
67 }
68}
69
70impl PartialEq for LuaString {
71 fn eq(&self, other: &Self) -> bool {
72 self.bytes == other.bytes
73 }
74}
75impl Eq for LuaString {}
76
77// ──────────────────────────────────────────────────────────────────────────────
78// PORT STATUS
79// source: src/lstring.h, src/lstring.c (TString)
80// target_crate: lua-types
81// confidence: high
82// todos: 0
83// port_notes: 0
84// unsafe_blocks: 0
85// notes: LuaString interned-string type. Mirrors C's TString with the short/long
86// variant distinction and the hash field; uses GcRef-style ptr
87// identity for interning.
88// ──────────────────────────────────────────────────────────────────────────────