2 Commits

Author SHA1 Message Date
cmounce d82e05505c Update packages, bump version to 0.2.0 2026-03-18 17:23:39 -07:00
cmounce 3e8bedb0c9 Clean up docs for Program enum, text functions 2026-03-18 17:20:53 -07:00
4 changed files with 54 additions and 29 deletions
Generated
+17 -17
View File
@@ -207,9 +207,9 @@ dependencies = [
[[package]]
name = "num_enum"
version = "0.7.5"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
dependencies = [
"num_enum_derive",
"rustversion",
@@ -217,9 +217,9 @@ dependencies = [
[[package]]
name = "num_enum_derive"
version = "0.7.5"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -229,9 +229,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.21.3"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "prettyplease"
@@ -368,9 +368,9 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.26.0"
version = "3.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
"getrandom",
@@ -401,18 +401,18 @@ dependencies = [
[[package]]
name = "toml_datetime"
version = "1.0.0+spec-1.1.0"
version = "1.0.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e"
checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.25.4+spec-1.1.0"
version = "0.25.5+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2"
checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1"
dependencies = [
"indexmap",
"toml_datetime",
@@ -422,9 +422,9 @@ dependencies = [
[[package]]
name = "toml_parser"
version = "1.0.9+spec-1.1.0"
version = "1.0.10+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4"
checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420"
dependencies = [
"winnow",
]
@@ -583,9 +583,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.15"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8"
dependencies = [
"memchr",
]
@@ -686,7 +686,7 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
[[package]]
name = "zztff"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"codepage-437",
"insta",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "zztff"
version = "0.1.0"
version = "0.2.0"
edition = "2024"
license = "MIT"
description = "Library for reading/writing ZZT worlds and boards"
+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>),
}