Expand description
rws gen model|route|migration|test: code generators for the
conventional layout (18.29.0).
rws gen model|route|migration|test: code generators for the
conventional layout (18.29.0).
rws gen model|route|migration|test (18.29.0, roadmap #88): code
generators for a project in the conventional layout
(crate::app_manifest), as a library — the rws gen command and the
dev MCP endpoint’s gen_* tools (crate::dev_mcp) are front ends.
| Generator | Writes | Adds to |
|---|---|---|
Generate::Model | src/models/<name>.rs (#[derive(Model)], id auto-increment, a test), migrations/NNNN_create_<table>.sql + .down.sql | src/models/mod.rs, src/lib.rs (pub mod models;), Cargo.toml (the model-<db> feature) |
Generate::Route | src/routes/<resource>.rs (typed handlers, register(app)) | src/routes/mod.rs, app() in src/lib.rs |
Generate::Migration | migrations/NNNN_<name>.sql + .down.sql | — |
Generate::Test | tests/<resource>.rs (TestClient against app()) | — |
The paths come from rws.app.toml. The output is pinned to this
release’s API: it compiles against the rust-web-server it came with
(CI generates into every starter and runs the generated tests).
plan only reads; it answers a Plan — each file created, edited
or left alone, with a unified diff. Plan::apply writes it. Nothing
is ever overwritten: a file that exists with other content is a
ChangeKind::Conflict (the diff shows what the generator would have
written) and the whole plan is refused, so running a generator twice
changes nothing the second time. Edits to existing files only add a
line (pub mod posts;, a feature, a register call) and are skipped
when it is there; what can’t be added safely is a Plan::notes line
saying what to add by hand.
use rust_web_server::generator::{plan, Field, Generate};
let request = Generate::Model {
name: "Post".into(),
fields: vec![Field::parse("title:String").unwrap(), Field::parse("views:i64").unwrap()],
db: None, // from Cargo.toml's model-* feature, else SQLite
timestamps: false,
soft_delete: false,
};
let plan = plan(".", &request).unwrap();
println!("{}", plan.render(true)); // what would change, with diffs
if !plan.has_conflicts() {
plan.apply(".").unwrap();
}Names are identifiers (letters, digits, _), so no path leaves the
project; field types are a fixed list (FieldType).
Structs§
- Field
- One
name:typefield of a model or a route’s resource. - Field
Type - A field’s type:
i64,i32,f64,bool,String, orOption<T>of one of those. - File
Change - One file of a
Plan. - GenError
- Why a generator refused.
- Plan
- What a generator would do: the files, and what to add by hand.
Enums§
- Base
Type - A column type: one of the fixed list, optionally
Option<…>. - Change
Kind - What happens to one file.
- Db
- The database a model’s migration is written for.
- Generate
- What to generate.
- Route
Action - One of the routes
rws gen routewrites for a resource.
Constants§
- EXIT_
CONFLICT - A conflict (a file exists with other content) or the project refused
(no
app(), no route module, …): nothing written. - EXIT_OK
- Written (or nothing to write: every file already as generated).
- EXIT_
USAGE - Bad arguments.
- FIELD_
TYPES - The types a field may have, as the error message lists them.
- MAX_
NAME_ LEN - The longest name
rws genaccepts (a resource, model, migration or field).
Functions§
- parse_
fields - Parse every
name:type; names must not repeat. - plan
- What
requestwould change in the project atdir(reads only). - requested
rws gen …asked for: the arguments aftergen.- run
- Run
rws gen <args>(the arguments aftergen), writing tooutanderr; answers the exit code (EXIT_OK,EXIT_CONFLICT,EXIT_USAGE).