Add an agents.md providing instructions on writing code. Note: I've generally been assuming that the agent can follow the style of existing code. So every line in this is something that I've specifically seen agents get wrong multiple times. Change-Id: Id6b6d4ff002a342de80233a95e5118f46a6a6964 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/23480 Reviewed-by: Takuto Ikuta <tikuta@google.com> Commit-Queue: Matt Stark <msta@google.com>
diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md new file mode 100644 index 0000000..478fcfe --- /dev/null +++ b/.agents/AGENTS.md
@@ -0,0 +1,70 @@ +# Rust Style Guidelines & Best Practices + +Please adhere to the following conventions and best practices when writing or +modifying Rust code in this repository: + +## Code Structure & Formatting + +* **Code Ordering**: Be consistent about the layout within a file. + * The structure should generally be: + 1. `mod` statements + 2. `use` statements + 3. Core code (structs, enums, impls, functions) + 4. Test module at the bottom: `#[cfg(test)]` + * Structs should always come immediately before their impl and impl traits. + * Full types should be defined before reference types (e.g. if we were + writing the standard library, String before str) +* **Inlining**: If you only use a variable once, prefer inlining it rather + than assigning it to a separate binding. +* **Collect**: Prefer using `.collect()` over manually iterating and + adding/pushing to data structures when possible. +* **Unused Variables**: Variables starting with `_` (e.g. `_var`) should only + be used if they are truly never used. If you begin using a variable that was + prefixed with an underscore, rename it to remove the underscore prefix. +* **Unsafe Code**: All `unsafe` blocks must be prefixed with a + `// Safety: <reason>` comment explaining why the usage is safe. +* **Warnings**: The code (including the tests) should compile with no warnings + and no clippy lint errors. + +## Imports & Use Statements + +* **Test-only Imports**: Imports that are only used inside tests should be + moved into a module block guarded by `#[cfg(test)]`. + +## Documentation + +* Anything marked as pub should have a docstring (starts with `///`). + +## Coding guidelines + +* Data members should not be public without good reason +* **FFI Boundary**: No FFI function calls (such as `extern "C"` blocks or raw + FFI calls) are allowed outside of the `ffi` submodule. The only exception is + `intern_string`. +* **No Statics**: Do not use global static variables or `thread_local!` + structures. They hinder concurrency, unit testing isolation, and + multi-session safety. Always prefer passing state and context explicitly via + arguments or trait objects. +* **Dynamic dispatch**: Never use dynamic dispatch (`dyn Trait`) in the hot + path (any code that could be called an arbitrary number of times by a + starlark rule). + * Avoid using dynamic dispatch (`dyn Trait`) in general if you can, but + you may use it to increase testability of code if it is not in the hot + path. + * Eg. Using `dyn Trait` to support a "real" version in production code and + a fake one in test code. +* `collect_repr` and `collect_str` + * collect_repr should be defined on starlark types iff `Debug` is + available on a type. It should just `write!(collector, "{:?}").unwrap()` + * collect_str should be defined on starlark types iff `Display` is + available on a type. It should just `write!(collector, "{}").unwrap()` +* **Error Handling**: Prefer using custom error enums with `thiserror` for + crate-level errors, rather than generic strings or custom hand-written + Display implementations. Let exceptions and failures bubble up naturally. +* **Crate Encapsulation**: Keep modules, structs, and fields private or + `pub(crate)` by default to maintain clean boundaries. Only use `pub` for APIs + that are intended to be consumed by other crates. + +# C++ Style guidelines and best practices + +* Never use `#pragma once` - use header guards instead.