[](https://github.com/tigerros/ruci/actions/workflows/test.yml)
[](https://github.com/tigerros/ruci/actions/workflows/clippy.yml)
[](https://app.codecov.io/gh/tigerros/ruci/)
[](https://docs.rs/ruci/)
[](https://crates.io/crates/ruci)
# ruci
**R**ust **U**niversal **C**hess **I**nterface.
This crate is a full implementation of the [UCI protocol](https://backscattering.de/chess/uci) using [`shakmaty`](https://crates.io/crates/shakmaty) for relevant types.
The UCI protocol is the most widely used way for chess GUI's to communicate with engines and vice versa.
Includes a struct to manage the I/O with an engine, but does not offer the same I/O management for engines themselves.
However, engines can still take advantage of this library to add strong typing to strings, as is demonstrated in the `engine` example.
`#![no_std]` compatible.
See also the [examples](https://github.com/tigerros/ruci/tree/master/examples).
You can run each one with `cargo run --package <example-name>`.
## Comparison
There's two other crates that I'm aware of which serve a similar purpose; [`vampirc-uci`](https://crates.io/crates/vampirc-uci) and [`shakmaty-uci`](https://crates.io/crates/shakmaty-uci).
`shakmaty-uci` is basically an improved version of `vampirc-uci`, so I'll only cover `shakmaty-uci`. Anyways, it:
- Doesn't separate the two types of messages (engine, GUI) and specific messages. It has one big enum which mostly uses enum fields for message data. This is inconvenient because you can't represent specific messages, just the whole `UciMessage` enum.
- Doesn't provide IO communication with an engine.
- Is 3 or more times slower than `ruci` when deserializing, 2 or more times slower when serializing. Benches don't cover that many types but there's a trend. Results available at [tigerros.github.io/ruci/bench](https://tigerros.github.io/ruci/bench), or you can view a more compact version in the summary of the latest [Bench workflow](https://github.com/tigerros/ruci/actions/workflows/bench.yml) run. Sources at [benches](https://github.com/tigerros/ruci/tree/master/benches).
- 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 `Cow`s (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`](https://crates.io/crates/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 `Cow`s 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. Requires `std`.
- `engine-async`: enables the `engine-sync` feature and adds async versions of all functions using [`tokio`](https://crates.io/crates/tokio).
- `tokio-process`: enables the `engine-async` and `tokio/process` features and adds a `tokio` version of `Engine::from_process`.
- `serde`: enables serde support for most types. All implementations are derived with no parameters. Requires `std`.