* veb: render_request, so an app can render a route without a listener
`veb.run` starts a server, which is the only way to get a page out of a veb app
today. That is right for a server and wrong for a site that should be a directory
of files: a static export needs the same HTML without a process, a port, or a
second rendering implementation that can drift from the first.
`veb.render_request[A, X](mut app, req)` is one call that does it. It generates
the route table from the app's methods and dispatches the request through the
same `handle_request_and_route` the server loop uses. `Context.conn` stays nil and
`takeover_mode` stays `.none`, so `send_response_to_client` has nothing to write
to and the result is read from `ctx.res` by the caller.
It exists as one function rather than by making `generate_routes` and
`handle_request_and_route` public: those take a `RequestParams` whose fields are
veb internals (`routes: &map[string]Route`), and publishing that struct would
freeze a shape nobody should depend on. The public surface stays what it is plus
one entry - `RawHtml`, `Result`, `no_result()`, `run`, `Context.error`, and now
this.
This is not a new mechanism. veb's own suite has done exactly this by hand since
before this helper existed - `route_arguments_test.v`, `cors_before_request_test.v`,
`middleware_response_lifetime_test.v` and `controller_static_regression_test.v`
each build a `RequestParams` and call the dispatcher directly. Four call sites
reaching for the same private path is the argument for making it callable, not a
new feature.
`vlib/veb/vrender_test.v` covers the body, the 200, the 404 for an unknown path,
repeatability across calls, and - the load-bearing one - that `conn` stays nil.
A future change that started a listener would pass every other assertion in the
file, which is why it gets one of its own.
`examples/veb/static_export/` is a static site generator on top of it: an explicit
route list (a crawler follows links and silently skips pages whose only link is
generated at runtime), the URL-to-file mapping GitHub Pages serves directly, and a
count check so a page missing from `dist/` fails the build instead of shipping
short. `-prod` is used in the example for the reason it is used everywhere: a
template error becomes a build error.
Measured: `v test vlib/veb` is 17 passed / 24 skipped / 0 failed on Windows; the
24 skips are the ones needing a network or display, which CI runs. The example
exports 3 files and previews the same 3 pages through the listener.
* veb: validate and preserve listener-free request dispatch
* examples: correct static exporter invocation
* veb: validate render request context before dispatch
---------
Co-authored-by: metif12 <metif12@users.noreply.github.com>
Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>