#chess #uci #parser #io

no-std ruci

A UCI (Universal Chess Interface) crate

41 releases (3 stable)

new 2.0.0 May 1, 2025
1.0.2 May 2, 2025
1.0.1 Apr 24, 2025
0.9.1 Mar 31, 2025
0.2.4 May 12, 2024

#229 in Game dev

Download history 3/week @ 2025-02-05 284/week @ 2025-02-12 42/week @ 2025-02-19 171/week @ 2025-02-26 780/week @ 2025-03-05 408/week @ 2025-03-12 260/week @ 2025-03-19 165/week @ 2025-03-26 68/week @ 2025-04-02 1/week @ 2025-04-09 233/week @ 2025-04-23

360 downloads per month

GPL-3.0 license

190KB
4.5K SLoC

tests clippy coverage docs.rs crates.io

ruci

Rust Universal Chess Interface.

This crate is a full implementation of the UCI protocol using shakmaty for relevant types. The UCI protocol is the most widely used way to communicate with chess engines and vice versa.

Specifically, this crate contains:

  • Types to represent every UCI message.
  • The means to convert strings to these types.
  • The means to convert these types to a string.
  • I/O management for both GUI's and engines (check out the examples, run them with cargo run -p {example_name}).

#![no_std] compatible.

Comparison

There's two other crates that I'm aware of which serve a similar purpose; vampirc-uci and shakmaty-uci. shakmaty-uci is basically an improved version of vampirc-uci, so I'll only cover shakmaty-uci. Anyways, it:

  • Doesn't separate messages. Instead, it has one enum which (mostly) uses enum fields for message data. This is inconvenient because you can't represent specific messages.
  • Doesn't provide I/O management.
  • Is 3 or more times slower than ruci when deserializing, 2 or more times slower when serializing. Results available at tigerros.github.io/ruci/bench, more compact version in the summary of the latest Bench workflow.
  • Has more tests, but I don't know about the coverage.
  • Uses owned versions of non-copy data. This makes for a cleaner API compared to using Cows (which is what ruci does), but it hurts performance. Converting a message to a string doesn't require owned data, and seeing as that is half of the functionality of this crate, it would be wasteful to force ownership.
  • Uses nom for parsing, whereas ruci doesn't pull in anything.

Benches

ruci has more benches per scenario than the other two. This is because it uses Cows to allow for borrowed or owned data. So, the suffix borrowed in bench names means that it is using a statically borrowed type rather than the owned type, e.g. &'static str instead of String. The flip side is the suffix owned.

Features

  • default: no features are enabled by default.
  • engine-sync: adds the Engine struct for communicating with an engine.
  • engine-async: adds async versions of Engine functions.
  • tokio-process: adds a tokio version of Engine::from_process.
  • gui-sync: adds the Gui struct for communicating with a GUI.
  • gui-async: adds async versions of Gui functions.
  • serde: enables serde support for most types. All implementations are derived with no parameters.

Dependencies

~0.9–9MB
~80K SLoC