# General requirements
- At the start of each task, read the README.md files from the project and the relevant directories to gather enough context to complete the task.
- Do NOT ever write unsafe Rust code; that includes `extern` blocks.
- Use British grammar and spelling.
- Prefer functional programming (e.g. `.map()`) over imperative (e.g. `for` loops).
# Dependencies
- At the start of each task, familiarise yourself with the `Cargo.toml` file and the dependencies it already has.
- Avoid introducing external dependencies for functionality that can be easily implemented with the standard library.
- If you think an external dependency is necessary, get approval from the user first.
- Use `cargo add` to add dependencies instead of editing the `Cargo.toml` file directly, so we can get the latest version.
# Testing
- Organise the internal structure of each unit test using the Arrange-Act-Assert (AAA) pattern, separating each part with a blank line. Do NOT add any comments to hint at the structure.
- All the branches of each unit under test should be covered, preferably with a unit test for each branch. In other words, each unit test should cover exactly one scenario.
- When changing the unit under test, make sure to add, update and/or remove tests accordingly.
- Only test the public API of the unit under test.
- Run the tests after making changes to the codebase.
- Run the tests with `RUST_BACKTRACE=full`.
- Prefer specialised assertions (e.g. equality checks) over simple boolean assertions.
- When a test fails, think critically about the cause of the failure, and consider the requirements. The issue may be the test or the unit under test.
# Troubleshooting
- When something goes wrong (e.g. tests fail, the code doesn't compile), fix the first issue and then try again. Do not try to fix multiple issues at once.
- When an assertion causes a test to fail, try to add or improve the assertion message, instead of adding a temporary debug statement.
- When debugging a tree-sitter structure, print the tree structure to the console using the following function:
```rust
fn debug_node(node: &Node, source_code: &str, indent: usize) -> String {
let mut result = String::new();
let indent_str = " ".repeat(indent);
result.push_str(&format!(
"{}Kind: {}, Text: {:?}\n",
indent_str,
node.kind(),
node.utf8_text(source_code.as_bytes()).unwrap_or("ERROR")
));
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
result.push_str(&debug_node(&child, source_code, indent + 2));
}
result
```
# Commit messages
- The title should be under 80 characters, succinctly summarise the changes and use the imperative mood (e.g. "Add tests for..." instead of "Adding tests for...").
- The body should be a detailed description of the changes, including the rationale for the changes and any other relevant information.