Clean up docs for Program enum, text functions

This commit is contained in:
2026-03-18 17:07:37 -07:00
parent 76149f0a69
commit 3e8bedb0c9
2 changed files with 36 additions and 11 deletions
+10 -6
View File
@@ -3,7 +3,8 @@ use codepage_437::CP437_WINGDINGS;
use super::errors::EncodeError;
/// Serialize a multi-line code string for an object or a scroll.
/// Uses ZZT's convention of CR-terminated lines.
///
/// Characters that do not have a CP437 equivalent will result in an [`EncodeError::EncodingError`].
pub fn encode_multiline(input: &str) -> Result<Vec<u8>, EncodeError> {
input
.chars()
@@ -33,8 +34,11 @@ pub fn decode_multiline(input: &[u8]) -> String {
.collect()
}
/// Serialize a single-line string for a board title.
/// Newlines cannot be encoded because ZZT interprets them as dingbats (♪).
/// Serialize a single-line string, such as a board title.
///
/// Newlines cannot be encoded because in single-line contexts, ZZT interprets that byte as a
/// dingbat, specifically the '♪' character. Passing a newline, or any non-CP437 character, will
/// result in an [`EncodeError::EncodingError`].
pub fn encode_oneline(input: &str) -> Result<Vec<u8>, EncodeError> {
input
.chars()
@@ -46,7 +50,7 @@ pub fn encode_oneline(input: &str) -> Result<Vec<u8>, EncodeError> {
.collect()
}
/// Deserialize a board title.
/// Deserialize a single-line string, such as a board title.
pub fn decode_oneline(input: &[u8]) -> String {
input.iter().map(|&x| CP437_WINGDINGS.decode(x)).collect()
}
@@ -60,7 +64,7 @@ mod tests {
encode_multiline(input).expect("Error in test")
}
fn serialize_title(input: &str) -> Vec<u8> {
fn serialize_line(input: &str) -> Vec<u8> {
encode_oneline(input).expect("Error in test")
}
@@ -73,7 +77,7 @@ mod tests {
#[test]
fn roundtrip_oneline() {
let bytes: Vec<u8> = (0..=255).collect();
assert_eq!(bytes, serialize_title(&decode_oneline(&bytes)))
assert_eq!(bytes, serialize_line(&decode_oneline(&bytes)))
}
#[test]
+26 -5
View File
@@ -351,15 +351,36 @@ pub struct Tile {
pub color: u8,
}
/// A stat's ZZT-OOP program.
/// A stat's ZZT-OOP program text.
///
/// In ZZT, stats can either have their own code or bind to another stat's code.
/// This enum prevents invalid states where both are set.
/// Stats must either have their own program or bind to another stat's program. This is either-or:
/// in ZZT, it is impossible to represent a stat that has both (or neither). This enum models that
/// constraint.
///
/// Internally, this is because ZZT uses a single `i16` like an enum discriminant. Zero or more
/// indicates the length of the program text, i.e., how many bytes follow the stat on disk. Negative
/// values are interpreted as negated bind indexes: -123 means no program text follows, and that the
/// stat instead shares code with the 123rd stat on the board.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Program {
/// The stat owns its own code.
/// The stat has its own program code.
///
/// This is the typical default for most stats. For stats that don't have or need a program, an
/// empty `String` is used. The text has a maximum of 32767 characters, though in ZZT 3.2 you
/// will encounter other limits before that.
///
/// Despite the name, this has more to do with ZZT's behavior than with Rust ownership.
Own(String),
/// The stat is bound to another stat (index into the stats list).
/// The stat is bound to the code at the given stat index.
///
/// Bind indexes are 0-based, with the asterisk that zero is not representable due to how ZZT
/// encodes bind indexes. The smallest possible value is 1, which represents being bound to the
/// stat that comes immediately after the player.
///
/// The largest representable bind index is 32768. zztff will successfully serialize this value,
/// though it's only useful as a curiosity and will likely crash ZZT: the index will definitely
/// be out of bounds because it is impossible to serialize a stat list that long without hitting
/// other limits in the file format. Indexes larger than that will result in an [`EncodeError`].
Bound(NonZero<u16>),
}