--- name: "codegen" description: Change generated code in this repository. Use when editing anything that looks like a generated file, when the Smithy models or the data under data/ change, when a codegen run leaves a diff, or when adding a generated module. license: "Apache-2.0" --- # Codegen Most of the API surface of `s3s` and `s3s-aws` is generated from the Smithy models in `data/`. A generated file is an output: the change belongs in the generator, and the output is committed together with it. ## The loop - `just crawl` refreshes the models and the error-code table under `data/` (`cargo run -p xtask -- crawl update`). - `just codegen` regenerates the workspace from that data, then runs `cargo fmt --all` and `cargo check`. - `just ci-rust` ends with `just assert_unchanged`, which requires an empty `git status`, so a codegen run that leaves a diff fails CI. Run `just codegen` before pushing anything that touches the models, the data or an emitter. ## The boundary - Generated files carry a `//! Auto generated by ...` marker. They live under `crates/s3s/src/{dto,xml,access,error,header}/generated.rs`, `crates/s3s/src/ops/generated/`, `crates/s3s-aws/src/{conv,proxy}/generated.rs` and `crates/s3s/tests/generated/`. - Hand-written code sits beside them (`dto/mod.rs`, `xml/mod.rs`, `ops/mod.rs`, ...). Edit that file, or the emitter, never the generated one. - An emitter change and the output it produces belong to the same commit: every commit has to leave a consistent tree, and `assert_unchanged` enforces exactly that. ## Where the generators live `codegen/src/v1/` holds one module per family (`dto.rs`, `xml.rs`, `ops.rs`, `s3_trait.rs`, `access.rs`, `error.rs`, `headers.rs`, `aws_conv.rs`, `aws_proxy.rs`, `gen_tests/`), driven from `mod.rs`: `run()` reads the model data and calls each module, `write_file` and `write_dir_file` write into the checkout, and `postprocess()` finishes the job. Output has to be deterministic and stable under `cargo fmt`, so iterate maps in a fixed order. ## The MinIO variant Every mergeable module is generated twice — into `generated.rs` and `generated_minio.rs` — and `postprocess()` merges the pair back into the first file: the differences become inline `#[cfg(feature = "minio")]` / `#[cfg(not(feature = "minio"))]` blocks, and the temporary `*_minio.rs` is deleted. Two consequences: - Verify both builds. `cargo test --all-features` and a plain `cargo test` execute different halves of a merged file, and the same holds for `cargo check` with and without the feature. - A type or a value subtree that differs between the two models is generated once per branch, so a test that covers it needs the same gates. ## Generated tests `codegen/src/v1/gen_tests/` writes the coverage test suite into `crates/s3s/tests/generated/`. The same rule applies there: extend the emitter instead of editing the generated tests by hand.