feat: add ltk_rst crate for RST (Riot String Table) support#125
feat: add ltk_rst crate for RST (Riot String Table) support#125
Conversation
Implements reading and writing of League of Legends .stringtable / fontconfig files following the ltk API style (from_reader/to_writer, thiserror, byteorder, xxhash-rust from workspace deps). Supports all four file versions (v2–v5), including the v2 font-config header, the deprecated mode byte present in v2–v4, and offset-based string deduplication on both read and write paths. Registers the crate in the league-toolkit umbrella behind a `rst` feature flag.
|
I will take a deeper look at this sometime during the week, it needs some changes before we can merge it. |
| @@ -0,0 +1,30 @@ | |||
| use xxhash_rust::xxh64::xxh64; | |||
| use crate::version::{RstMode, RstVersion}; | ||
|
|
||
| /// Magic bytes at the start of every RST file: `"RST"`. | ||
| pub const MAGIC: [u8; 3] = [0x52, 0x53, 0x54]; |
There was a problem hiding this comment.
| pub const MAGIC: [u8; 3] = [0x52, 0x53, 0x54]; | |
| pub const MAGIC: &[u8; 3] = b"RST"; |
| pub version: RstVersion, | ||
|
|
||
| /// Optional font-config string. Only present (and written) in v2 files. | ||
| pub config: Option<String>, |
There was a problem hiding this comment.
config and mode should be encoded alongside the version enum, since they are only valid for given versions
| pub fn to_writer(&self, writer: &mut impl Write) -> Result<(), RstError> { | ||
| let hash_type = self.version.hash_type(); | ||
|
|
||
| let mut header: Vec<u8> = Vec::new(); |
There was a problem hiding this comment.
why are we writing header bytes to an intermediate buffer?
| } | ||
| } | ||
|
|
||
| fn read_null_terminated(reader: &mut impl Read) -> Result<String, io::Error> { |
There was a problem hiding this comment.
do we not have a helper for this already?
- Use ltk_hash instead of direct xxhash-rust dependency - Use byte string literal for MAGIC constant - Encode config/mode in RstVersion enum variants - Write directly to writer instead of intermediate buffer - Use ltk_io_ext::read_str_until_nul helper
| pub entries: HashMap<u64, String>, | ||
| } | ||
|
|
||
| impl RstFile { |
There was a problem hiding this comment.
I don't think it makes sense to have an RstFile struct. We can rename it to Stringtable and have it be constructed through from_rst_reader fn
| // Read mode byte for versions that have it | ||
| if version.has_mode_byte() { | ||
| let mode = RstMode::from_u8(reader.read_u8()?); | ||
| match &mut version { | ||
| RstVersion::V2 { | ||
| mode: ref mut m, .. | ||
| } => *m = mode, | ||
| RstVersion::V3 { mode: ref mut m } => *m = mode, | ||
| RstVersion::V4 { mode: ref mut m } => *m = mode, | ||
| _ => {} | ||
| } | ||
| } |
There was a problem hiding this comment.
Can we do this differently so its actually readable code
| /// - **V5** — simple (39-bit) hashing, no mode byte. | ||
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
| pub enum RstVersion { |
There was a problem hiding this comment.
I don't think it makes sense to store any sort of data inside of this struct other than the actual version number. It just makes the code look confusing.
| } | ||
|
|
||
| /// Returns the mode byte value, if applicable. | ||
| pub fn mode(&self) -> RstMode { |
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct RstFile { | ||
| /// File version (encodes config and mode alongside version-specific data). | ||
| pub version: RstVersion, |
There was a problem hiding this comment.
Don't think we need to store the version for later use in the struct.
When saving/writing we can use the latest version.
Implements reading and writing of League of Legends .stringtable / fontconfig files following the ltk API style (from_reader/to_writer, thiserror, byteorder, xxhash-rust from workspace deps).
Supports all four file versions (v2–v5), including the v2 font-config header, the deprecated mode byte present in v2–v4, and offset-based string deduplication on both read and write paths.
Registers the crate in the league-toolkit umbrella behind a
rstfeature flag.