{"id":33930738,"url":"https://github.com/vampirc/vampirc-uci","last_synced_at":"2025-12-12T12:07:05.999Z","repository":{"id":34221971,"uuid":"170590845","full_name":"vampirc/vampirc-uci","owner":"vampirc","description":"A Universal Chess Interface (UCI) protocol parser and message generator.","archived":false,"fork":false,"pushed_at":"2022-03-27T21:23:31.000Z","size":164,"stargazers_count":23,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-30T05:20:21.861Z","etag":null,"topics":["chess","parser","rust","rust-crate","uci"],"latest_commit_sha":null,"homepage":"https://vampirc.kejzar.si","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vampirc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-13T22:42:17.000Z","updated_at":"2025-10-17T18:59:01.000Z","dependencies_parsed_at":"2022-08-08T00:02:06.831Z","dependency_job_id":null,"html_url":"https://github.com/vampirc/vampirc-uci","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/vampirc/vampirc-uci","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vampirc%2Fvampirc-uci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vampirc%2Fvampirc-uci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vampirc%2Fvampirc-uci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vampirc%2Fvampirc-uci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vampirc","download_url":"https://codeload.github.com/vampirc/vampirc-uci/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vampirc%2Fvampirc-uci/sbom","scorecard":{"id":915590,"data":{"date":"2025-08-11","repo":{"name":"github.com/vampirc/vampirc-uci","commit":"c74c2ea016f0d5864a1a2012d240d05b9eab6a93"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/12 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/rust.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/rust.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/vampirc/vampirc-uci/rust.yml/master?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during GetBranch(release): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T20:51:10.519Z","repository_id":34221971,"created_at":"2025-08-24T20:51:10.519Z","updated_at":"2025-08-24T20:51:10.519Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27682509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-12T02:00:06.775Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chess","parser","rust","rust-crate","uci"],"created_at":"2025-12-12T12:07:05.147Z","updated_at":"2025-12-12T12:07:05.991Z","avatar_url":"https://github.com/vampirc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vampirc-uci [![Documentation Status](https://docs.rs/vampirc-uci/badge.svg)](https://docs.rs/vampirc-uci)\n\nVampirc UCI is a [Universal Chess Interface (UCI) protocol](https://en.wikipedia.org/wiki/Universal_Chess_Interface) parser and\nserializer. \n\nThe UCI protocol is a way for a chess engine to communicate with a chessboard GUI, such as [Cute Chess](https://cutechess.com/).\n\nThe [Vampirc Project](https://vampirc.kejzar.si) is a chess engine and chess library suite, written in Rust. It is named for the\nSlovenian grandmaster [Vasja Pirc](https://en.wikipedia.org/wiki/Vasja_Pirc), and, I guess, vampires? I dunno.\n\nVampirc UCI uses the [PEST parser](https://github.com/pest-parser/pest) to parse the UCI messages. If you want to build your own\nabstractions of the protocol, the corresponding PEG grammar is available [here](https://github.com/vampirc/vampirc-uci/blob/master/res/uci.pest).\n\n## Installing the library\n\nTo use the crate, declare a dependency on it in your Cargo.toml file:\n\n```toml\n[dependencies]\nvampirc-uci = \"0.11\"\n```\n\nThen reference the `vampirc_uci` crate in your crate root:\n```rust\nextern crate vampirc_uci;\n```\n\n## Usage\n\n1. Choose and import one of the `parse..` functions. See [Choosing the parsing function](#choosing-the-parsing-function).\n\n```rust\nuse vampirc_uci::parse;\n``` \n\n2. Some other useful imports (for message representation):\n\n```rust\nuse vampirc_uci::{UciMessage, MessageList, UciTimeControl, Serializable};\n```\n\n3. Parse some input:\n\n```rust\nlet messages: MessageList = parse(\"uci\\nposition startpos moves e2e4 e7e5\\ngo ponder\\n\");\n```\n\n4. Do something with the parsed messages:\n\n```rust\nfor m in messages {\n    match m {\n        UciMessage::Uci =\u003e {\n            // Initialize the UCI mode of the chess engine.\n        }\n        UciMessage::Position { startpos, fen, moves } =\u003e {\n            // Set up the starting position in the engine and play the moves e2-e4 and e7-e5\n        }\n        UciMessage::Go { time_control, search_control } {\n            if let Some(tc) = time_control {\n                match tc {\n                    UciTimeControl::Ponder =\u003e {\n                        // Put the engine into ponder mode (\"think\" on opponent's time)\n                    }\n                    _ =\u003e {...}\n                }\n            }\n        }\n        _ =\u003e {...}\n    }\n}\n```\n\n5. Outputting the messages\n\n```rust\n    let message = UciMessage::Option(UciOptionConfig::Spin {\n                name: \"Selectivity\".to_string(),\n                default: Some(2),\n                min: Some(0),\n                max: Some(4),\n            });\n    \n    println!(message); // Outputs \"option name Selectivity type spin default 2 min 0 max 4\"\n```\n\n6. Or, parse and handle input line by line, from, for example, `stdin`:\n```rust\nuse std::io::{self, BufRead};\nuse vampirc_uci::{UciMessage, parse_one};\n\nfor line in io::stdin().lock().lines() {\n     let msg: UciMessage = parse_one(\u0026line.unwrap());\n     println!(\"Received message: {}\", msg);\n}\n```\n\n## Choosing the parsing function\n\nThere are several parsing functions available, depending on your need and use case. They differ in what\nthey return and how they handle unrecognized input. The following table may be of assistance in selecting the\nparsing function:\n\n| Function             | Returns                                 | Can skip terminating newline | On unrecognised input...                    | \n| -------------------- | ----------------------------------------|------------------------------|---------------------------------------------|\n| `parse`              | `MessageList` (a `Vec` of `UciMessage`) | On last command              | Ignores it                                  |\n| `parse_strict`       | `MessageList` (a `Vec` of `UciMessage`) | On last command              | Throws a `pest::ParseError`                 |\n| `parse_with_unknown` | `MessageList` (a `Vec` of `UciMessage`) | On last command              | Wraps it in a `UciMessage::Unknown` variant |\n| `parse_one`          | `UciMessage`                            | Yes                          | Wraps it in a `UciMessage::Unknown` variant |\n\nFrom my own experience, I recommend using either `parse_with_unknown` if your string can contain multiple commands, or\nelse `parse_one` if you're doing line by line parsing. That way, your chess engine or tooling can at least log \nunrecognised input, available from `UciMessage::Unknown(String, Error)` variant.  \n\n## Integration with the chess crate (since 0.9.0)\n\nThis library (optionally) integrates with the [chess crate](https://crates.io/crates/chess). First, include the \n`vampirc-uci` crate into your project with the `chess` feature:\n\n```toml\n[dependencies]\nvampirc-uci = {version = \"0.11\", features = [\"chess\"]}\n```\n\nThis will cause the vampirc_uci's internal representation of moves, squares and pieces to be replaced with `chess` \ncrate's representation of those concepts. Full table below:\n\n| vampirc_uci 's representation | chess' representation |\n| ----------------------------- | --------------------- |\n| `vampirc_uci::UciSquare`      | `chess::Square`       |\n| `vampirc_uci::UciPiece`       | `chess::Piece`        |\n| `vampirc_uci::UciMove`        | `chess::ChessMove`    |\n\n---\n**WARNING**\n\n`chess` is a fairly heavy create with some heavy dependencies, so probably only use the integration feature if you're \nbuilding your own chess engine or tooling with it. \n\n---\n\n\n## API\n\nThe full API documentation is available at [docs.rs](https://docs.rs/vampirc-uci/).\n\n### New in 0.11.1\n* Improved `parse_with_unknown(\u0026str)` so that it correctly recognizes as much of input as possible. For example, whereas \nearlier the input `uci\\ndebug on\\nucinewgame\\nabc\\nstop\\nquit` would be returned as a single `Uci::Unknown` message, the \nimproved grammar support will return six separate messages, five of which will be proper UCI messages, while wrapping\n'abc' into `Uci::Unknown`.\n* A [fix](https://github.com/vampirc/vampirc-uci/pull/23) for incorrect serialization to string of the `btime`\nparameter, thanks to [@analog_hors](https://github.com/analog-hors).\n* Support for the [chess crate](https://crates.io/crates/chess) v. 3.2.0.\n\n### New in 0.11.0\n* Support for negative times, such as negative time left and time increment, as discussed in \n[vampirc-uci doesn't recognize negative times #16](https://github.com/vampirc/vampirc-uci/issues/16).\nTo support negative durations, the representation of millisecond-based time quantities has been switched\nfrom Rust standard library's `std::time::Duration` to the [chrono crate's](https://crates.io/crates/chrono)\n`chrono::Duration` ([doc](https://docs.rs/chrono/0.4.15/chrono/struct.Duration.html)). This is an API-breaking change, hence the version increase.\n* Fix for [vampric-uci-19](https://github.com/vampirc/vampirc-uci/issues/19), a sometimes incorrect parsing of the `go` message.\n\n### New in 0.10.1\n* Republish as 0.10.1 due to improper publish. \n\n### New in 0.10.0\n* Added the `parse_one(\u0026str)` method that parses and returns a single command, to be used in a loop\nthat reads from `stdin` or other `BufReader`. See example above.\n* Changed the internal representation of time parameters from `u64` into `std::time::Duration` (breaking \nchange).\n* Relaxed grammar rules now allow that the last command sent to `parse()` or friends doesn't need to\nhave a newline terminator. This allows for parsing of, among others, a single command read in a loop from\n`stdin::io::stdin().lock().lines()`, which strips the newline characters from the end -\nsee [vampirc-uci-14](https://github.com/vampirc/vampirc-uci/issues/14).\n* Marked the `UciMessage::direction(\u0026self)` method as public.\n\n### New in 0.9.0\n* (Optional) integration with [chess crate](https://crates.io/crates/chess) (see above).\n* Removed the explicit Safe and Sync implementations.\n\n### New in 0.8.3\n\n* Added the `UciMessage::info_string()` utility function.\n* Allowed the empty `go` command (see [Parser cannot parse \"go\\n\"](https://github.com/vampirc/vampirc-uci/issues/9)).\n\n### New in 0.8.2\n\n* Added `ByteVecUciMessage` as a `UciMessage` wrapper that keeps the serialized form of the message in the struct as a byte Vector. Useful if\nyou need to serialize the same message multiple types or support `AsRef\u003c[u8]\u003e` trait for funnelling the messages into a `futures::Sink` or\nsomething.\n* Modifications for integration with async [async-std](https://github.com/async-rs/async-std) based [vampirc-io](https://github.com/vampirc/vampirc-io).\n\n### New in 0.8.1\n\n* Added `parse_with_unknown()` method that instead of ignoring unknown messages (like `parse`) or throwing an error (like `parse_strict`) returns\nthem as a `UciMessage::Unknown` variant.\n\n### New in 0.8.0\n\n* Support for parsing of the `info` message, with the [UciAttributeInfo](https://docs.rs/vampirc-uci/0.8/vampirc_uci/uci/enum.UciInfoAttribute.html) \nenum representing all 17 types of messages described by the UCI documentation, as well as any other info message via the\n[Any variant](https://docs.rs/vampirc-uci/0.8/vampirc_uci/uci/enum.UciInfoAttribute.html#variant.Any).\n\n### New in 0.7.5\n\n* Support for parsing of the `option` message.\n* Proper support for `\u003cempty\u003e` strings in `option` and `setoption`.\n\n## vampirc-io\n\nThis section used to recommend using the [vampirc-io](https://github.com/vampirc/vampirc-io) crate to connect your\nUCI-based chess engine to the GUI, but honestly, with recent advances to Rust's async stack support, it is probably\njust easier if you do it yourself using, for example, the [async-std library](https://github.com/async-rs/async-std).\n\n## Limitations and 1.0\n\nThe library is functionally complete – it supports the parsing and serialization to string of all the messages\ndescribed by the UCI specification. Before the 1.0 version can be released, though, this library needs to be battle\ntested more, especially in the upcoming [Vampirc chess engine](https://vampirc.kejzar.si).\n\nFurthermore, as I am fairly new to Rust, I want to make sure the implementation of this protocol parser is Rust-idiomatic\nbefore releasing 1.0. For this reason, the API should not be considered completely stable until 1.0 is released. \n\nAdditionally, some performance testing would also not go amiss.\n\n### Supported engine-bound messages (100%)\n\n* `uci`\n* `debug`\n* `isready`\n* `register`\n* `position`\n* `setoption`\n* `ucinewgame`\n* `stop`\n* `ponderhit`\n* `quit`\n* `go`\n\n### Supported GUI-bound messages (100%)\n\n* `id`\n* `uciok`\n* `readyok`\n* `bestmove`\n* `copyprotection`\n* `registration`\n* `option`\n* `info`\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvampirc%2Fvampirc-uci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvampirc%2Fvampirc-uci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvampirc%2Fvampirc-uci/lists"}