Skip to main content

Crate sashite_feen

Crate sashite_feen 

Source
Expand description

§Field Expression Encoding Notation (FEEN)

A no_std, unsafe-free, allocation-free implementation of the FEEN v1.0.0 specification, built on EPIN (piece tokens) and SIN (style tokens).

FEEN encodes a complete board-game position as three space-separated fields:

<piece-placement> <hands> <style-turn>

for example the chess starting position -rnbqk^bn-r/+p+p+p+p+p+p+p+p/8/8/8/8/+P+P+P+P+P+P+P+P/-RNBQK^BN-R / C/c.

§Allocation-free by design

Unlike a fixed-size token, a position is variable-sized, so this crate is built as a borrowing, streaming validator rather than a parser that returns an owned value:

  • Feen::parse validates an input string in a single pass and returns a Feen view that borrows it — nothing is materialized, nothing is allocated.
  • The view exposes the geometry (Feen::shape), the square and piece counts, the active player, and lazy iterators over board squares and hand items.
  • An owned position is available behind the alloc feature as a sashite_qi::Qi, produced by Feen::to_qi; encode turns one back into a canonical FEEN string. That conversion is the only part of the crate that allocates.

The default build does not even link the alloc crate.

§Bounds (assumed for safety)

Inputs are bounded before and during parsing, which keeps memory and time bounded even on untrusted input:

The last point makes this crate intentionally stricter than the FEEN specification, which also permits irregular boards: such inputs are rejected with ParseError::BoardNotRegular.

§Example

use sashite_feen::{Feen, Side};

let feen = Feen::parse("8/8/8/8/8/8/8/8 / C/c")?;
assert_eq!(feen.square_count(), 64);
assert_eq!(feen.piece_count(), 0);
assert_eq!(feen.active_side(), Side::First);

assert!(Feen::is_valid("k^+p4+PK^ / C/c")); // a 1D, 8-square board

§Guarantees

  • no_std and allocation-free core. Validation and iteration borrow the input; nothing touches the heap unless the alloc feature is used.
  • No unsafe, no regex engine. Parsing is a single left-to-right pass over raw bytes, with bounded integer arithmetic.
  • Built on EPIN and SIN. Piece and style tokens are validated by those crates; FEEN adds only the field, dimensional, canonicality, and cardinality rules.

Re-exports§

pub use sashite_epin;
pub use sashite_sin;
pub use sashite_qi;

Modules§

feen_string
A #[serde(with = "…")] adapter that (de)serializes a Qi position as its canonical FEEN string. Available with the serde feature. A #[serde(with = "…")] adapter that (de)serializes a sashite_qi::Qi position as its canonical FEEN string, rather than structurally.

Structs§

Feen
A validated FEEN position that borrows its source string.
HandItem
A single item in a player’s hand: a piece together with its multiplicity.
HandIter
A lazy iterator over the items of one hand.
Shape
The shape of a regular board: the size of each of its dimensions.
SquareIter
A lazy iterator over board squares in FEEN traversal order.

Enums§

ParseError
The reason a string is not a valid, canonical FEEN position.
Side
The two-side model (First / second) shared across the ecosystem, re-exported from sashite_sin. Used here for the active player and the hand attribution. The camp a player belongs to.

Constants§

MAX_DIMENSIONS
Maximum number of board dimensions (1D, 2D, or 3D).
MAX_DIMENSION_SIZE
Maximum number of cells along any single dimension.
MAX_STRING_LENGTH
Maximum length, in bytes, of a FEEN string.

Functions§

encode
Canonical FEEN serialization of an owned Qi position. Available with the alloc feature. Encodes an owned Qi position as its canonical FEEN string.
write_feen
Canonical FEEN serialization of an owned Qi position. Available with the alloc feature. Writes the canonical FEEN string for position to a fmt::Write sink.