Skip to main content

Module state

Module state 

Source
Expand description

Persistent game state: the state.json file shared with the Python implementation.

The Rust binary is a drop-in replacement for the Python one. Students switch binaries in the middle of the semester, so both must read and write the very same state.json (schema 2.1). This module therefore reproduces what pydantic’s GameState.model_dump_json(indent=2) writes, byte for byte, and reads every older layout the Python version has written.

  • State and LevelCompletion are the model, together with the pure progress mutations of core/progress.py.
  • StateStore loads, atomically saves and removes the file. A corrupt or unsupported file is an error, never “no state”, and loading never overwrites it.
  • state_dir and default_workspace say where things live. They take the relevant environment values as arguments: this module never reads the environment or the working directory itself.

§File format

Field order, 2-space indentation, "key": value spacing, the lack of a trailing newline and non-ASCII text written as-is all match pydantic. Timestamps are naive local times written as YYYY-MM-DDTHH:MM:SS, with .ffffff (always six digits) appended only when the microseconds are not zero. The per-level maps keep their insertion order, like Python dicts, and level IDs stay strings ("1.12"). Unknown fields are ignored. Only username, workspace, current_level and start_time are required; a missing version means 1.0.

Files of version 1.0 and 2.0 predate the section reordering of 2.1; loading remaps their level IDs (see State) and the next save writes version 2.1.

§Example

use chrono::NaiveDate;
use shellgame::state::{State, StateStore};

let dir = tempfile::tempdir()?;
let store = StateStore::new(dir.path());
assert_eq!(store.load()?, None);

let now = NaiveDate::from_ymd_opt(2026, 3, 1).unwrap().and_hms_opt(10, 20, 30).unwrap();
let mut state = State::new("jana", "/tmp/shellgame-jana", now);
state.record_attempt("0.0");
store.save(&state)?;

assert_eq!(store.load()?, Some(state));

Structs§

LevelCompletion
The record of one finished level.
State
Everything the game remembers about one player: the contents of state.json.
StateStore
Reads and writes the state file in one state directory.

Enums§

StateError
A failure to read, write or remove the state file.

Constants§

CURRENT_STATE_VERSION
Schema version written by this binary, and by the Python implementation since the section reordering.
STATE_FILE_NAME
Name of the state file inside the state directory.

Functions§

default_workspace
Workspace directory of a new game: $SHELLGAME_WORKSPACE, else /tmp/shellgame-{user}.
now
The current local time as a naive timestamp, truncated to microseconds like Python’s datetime.now().
state_dir
Directory that holds the state file.