Skip to main content

rakata_formats/ltr/
writer.rs

1//! LTR binary writer.
2
3use std::io::{Cursor, Write};
4
5use crate::binary::{write_f32, write_u8};
6
7use super::{
8    Ltr, LtrBinaryError, LtrProbabilityBlock, LTR_CHARACTER_COUNT_U8, LTR_MAGIC, LTR_VERSION_V10,
9};
10
11/// Writes an LTR file to a writer.
12///
13/// # Errors
14///
15/// [`LtrBinaryError::Io`] when the writer fails, which is the only way this
16/// can fail: the letter count is a constant of the format and the probability
17/// tables are fixed-size arrays, so there is no value here to reject. A
18/// partial file may already have been written.
19#[cfg_attr(
20    feature = "tracing",
21    tracing::instrument(level = "debug", skip(writer, ltr))
22)]
23pub fn write_ltr<W: Write>(writer: &mut W, ltr: &Ltr) -> Result<(), LtrBinaryError> {
24    writer.write_all(&LTR_MAGIC)?;
25    writer.write_all(&LTR_VERSION_V10)?;
26    write_u8(writer, LTR_CHARACTER_COUNT_U8)?;
27
28    write_block(writer, &ltr.singles)?;
29    for block in ltr.doubles.iter() {
30        write_block(writer, block)?;
31    }
32    for row in ltr.triples.iter() {
33        for block in row.iter() {
34            write_block(writer, block)?;
35        }
36    }
37
38    Ok(())
39}
40
41/// Serializes an LTR file into a byte vector.
42///
43/// # Errors
44///
45/// Nothing in practice. [`write_ltr`] fails only on I/O and the `Vec` target
46/// has none, so the `Result` is here for shape.
47#[cfg_attr(feature = "tracing", tracing::instrument(level = "debug", skip(ltr)))]
48pub fn write_ltr_to_vec(ltr: &Ltr) -> Result<Vec<u8>, LtrBinaryError> {
49    let mut cursor = Cursor::new(Vec::new());
50    write_ltr(&mut cursor, ltr)?;
51    Ok(cursor.into_inner())
52}
53
54fn write_block<W: Write>(
55    writer: &mut W,
56    block: &LtrProbabilityBlock,
57) -> Result<(), LtrBinaryError> {
58    for chance in block
59        .start
60        .iter()
61        .chain(block.middle.iter())
62        .chain(block.end.iter())
63    {
64        write_f32(writer, *chance)?;
65    }
66    Ok(())
67}