sokoban_elements/lib.rs
1#![cfg_attr(doc, doc = include_str!("./lib.rs.md"))]
2
3// Serde rules for this crate, because the `serde` feature is not JSON-only. Compact formats
4// (`bincode`, MessagePack, ...) write struct fields *positionally*, with no field names on the
5// wire, so anything that makes the field sequence depend on a value's contents produces output the
6// same code cannot read back. Banned crate-wide, in every `derive` and every hand-written impl:
7//
8// skip_serializing, skip_serializing_if, skip_deserializing, flatten, untagged
9//
10// `flatten` and `untagged` are doubly disqualified: both buffer through serde's `Content` and need
11// a self-describing format, so they break on `bincode` however stable the field sequence is.
12//
13// `#[serde(default)]` and `deny_unknown_fields` are unaffected and used freely. Nothing enforces
14// this - a violation costs nothing under `serde_json` and silently breaks the compact formats.
15//
16// `deny_unknown_fields` has a placement rule of its own: the three wire-format mirrors below only,
17// never on `Puzzle`, `Collection` (`src/puzzle.rs`) or `ReaderSettings` / `WriterSettings`
18// (`src/io/settings.rs`), all four of which downstream code may want to flatten into a wrapper of
19// its own. `src/puzzle.rs` has the reasoning.
20//
21// `GameBoard`, `SavedGame` and `SokobanPlus` have private fields with invariants only their
22// constructors enforce, so each has a hand-written impl over a private mirror struct at the bottom
23// of its file rather than a `derive`; the four ID newtypes use `serde(try_from, into)` so a
24// `derive` cannot bypass their bound checks. See also `src/puzzle.rs` on where
25// `deny_unknown_fields` may go.
26
27mod board_area;
28mod direction;
29mod game_board;
30mod io;
31mod piece;
32mod point2d;
33mod puzzle;
34mod rle;
35mod saved_game;
36mod size2d;
37mod sokoban_plus;
38mod static_board_analysis;
39mod tessellation;
40mod tile;
41mod utilities;
42
43pub use board_area::{BoardArea, BoardAreaIntoIter, BoardAreaIter};
44pub use direction::{Direction, DirectionsSet, DirectionsSetIter};
45pub use game_board::{
46 BoardSyntaxError, BoardSyntaxErrorKind, GameBoard, GameBoardIter, HorizontalEdge, MirrorAxis,
47 Rotation, VerticalEdge,
48};
49pub use io::{
50 FileFormat, IoReadError, IoReadErrorKind, IoWriteError, ReaderSettings, WriterSettings,
51};
52pub use piece::{BoxID, Boxbox, Goal, GoalID, PieceIdError, PieceIdErrorKind, Pusher, PusherID};
53pub use point2d::Point2D;
54pub use puzzle::{Collection, Puzzle};
55pub use saved_game::{
56 SavedGame, SavedGameSyntaxError, SavedGameSyntaxErrorKind, SolvingMode, Step,
57};
58pub use size2d::Size2D;
59pub use sokoban_plus::{PlusID, SokobanPlus, SokobanPlusSyntaxError, SokobanPlusSyntaxErrorKind};
60pub use static_board_analysis::StaticBoardAnalysis;
61pub use tessellation::Tessellation;
62pub use tile::{TileKind, TileShape};