Skip to main content

Crate renox

Crate renox 

Source
Expand description

§Renox

A batteries-included web framework for Rust, inspired by Laravel. Axum + HTMX + Alpine.js + SQLite or PostgreSQL.

use renox::prelude::*;

struct Hello;

impl Module for Hello {
    fn name(&self) -> &'static str { "hello" }

    fn routes(&self) -> Routes {
        Routes::new().get("/", home).name("home")
    }
}

async fn home() -> View {
    view("home.html", context! { title => "Hello from Renox" })
}

fn main() -> renox::Result {
    App::new().module(Hello).run()
}

Re-exports§

pub use axum;
pub use tokio;

Modules§

analytics
Analytics events, with Google Analytics 4 and Tag Manager configured in .env (see AnalyticsConfig).
anyhow
anyhow, for errors with context: renox::anyhow::anyhow!("…"), .context("…"), Error::permanent(err). github crates-io docs-rs
audit
An audit trail: who did what, to which record, from where. Opt in with App::module(Audit), which also records every auth event (logins, failed logins, lockouts, password and profile changes, deleted accounts). Record the app’s own actions with record:
auth
Authentication and authorization: the users table, password hashing, session login with “remember me”, route guards, policies and gates.
cache
A key-value cache for expensive results.
chart
Dashboards: numbers over time from the database (Trend over a Period, giving a Series), and the chart(…) template function that draws them (line, area, bar, pie, doughnut, and scatter or bubble charts of points) as plain HTML and SVG, with the UI kit’s stat, widget and period_filter around them.
chrono
Chrono: Date and Time for Rust
clap
Command Line Argument Parser for Rust
command
The app’s own commands, run like the built-in ones: my-app admin:create --email a@b.c (or rnx admin:create … during development).
context
Values that belong to the current request or job, such as the current team of a multi-tenant app, readable anywhere down the call stack without passing them along (a model’s default_scope, a listener, a helper).
cors
CORS configuration for Routes::cors_layer. Middleware which adds headers for CORS.
db
Database access (SQLite, or PostgreSQL with the postgres feature): the connection pool, raw SQL, models, queries, pagination, migrations and factories.
events
Events and listeners, for decoupling modules: the order module emits OrderPlaced, and the stock and mail modules react to it.
fake
A library for generating fake data.
grid
Data grids: a table that fills the screen, with server-side filters, sorting and pagination, columns each user picks per screen size, frozen columns, grouped headers and cells of any kind.
http
An HTTP client for calling other services (payment gateways, shipping rates, webhooks you send), with timeouts, retries and a fake for tests.
i18n
Translations for app texts, and the language of each request.
import
Imports: the rows of a CSV file, each checked with a form’s rules, then written in one transaction (Filament’s import action).
mail
Sending email: SMTP in production, the log or memory in development and tests, HTML templates with a text version, and a preview page.
maintenance
Maintenance mode: my-app down makes the site answer 503 (with errors/503.html or the built-in error page) until my-app up.
minijinja
minijinja, for the app’s own template filters and functions (App::templates(|env| …) gets a minijinja::Environment).
prelude
What most files of an app import: use renox::prelude::*; brings the app builder, modules and routes, models and queries, validation, auth, views, jobs and events, and axum’s extractors and responses.
prompt
Questions an app command asks when it runs in a terminal, like Laravel’s $this->ask(), secret(), confirm() and choice().
queue
Background jobs stored in SQLite, with retries and a failed-jobs table.
rate_limit
Per-route rate limits: Routes::throttle(60, Duration::from_secs(60)).
report
Error reports: every error a person should look at (a 500, a job that failed for good, a scheduled task that failed), handed to the app’s reporters, e.g. to send them to Sentry or a chat channel.
schedule
Tasks that run on a schedule, defined in code and run by serve (or my-app schedule:work).
security
Security headers on every response: a Content-Security-Policy (see CspMode, CSP in .env), X-Content-Type-Options, Referrer-Policy, X-Frame-Options, and HSTS in production over https. A header the handler already set is kept.
select
Options a searchable select asks the server for: the endpoint behind the UI kit’s select(…, options_url=…, editable=…).
seo
Being found and shared: seo() in templates (title, description, canonical URL, OpenGraph and Twitter cards), robots.txt, sitemaps, and the head tags for Search Console, Google Analytics 4 and Tag Manager.
serde
Serde
serde_json
Serde JSON
shell
my-app db:shell: a small SQL prompt on the app’s database, so neither sqlite3 nor psql is needed (on servers or Windows).
signed
Signed URLs: links that can’t be altered and may expire, e.g. for email verification. state.signed_url(...) builds one; the ValidSignature extractor rejects tampered or expired ones with 403.
storage
File storage on the local disk, or on S3-compatible storage (AWS S3, Cloudflare R2, MinIO) with the s3 feature.
testing
Testing helpers, in the spirit of Laravel’s HTTP tests.
timezone
The app’s time zone (APP_TIMEZONE): an IANA name such as Asia/Jakarta or Europe/Amsterdam (daylight saving time included), a fixed offset such as +07:00, or UTC. Scheduled tasks and the date template filter use it.
toast
Toasts: short messages that confirm what just happened (“Saved”), shown over the page and announced to screen readers.
upload
Uploaded files. A form field of type Upload (or Option<Upload>) receives the file from a multipart/form-data post through Valid<T>:
validation
Form validation with Laravel-style rules, database-backed unique and exists, and English messages (an app translates them in its lang files).
view
Views: MiniJinja templates, the View response and template globals.
webhook
Webhooks: calls from payment gateways and other services, received safely. For each call Renox:

Macros§

context
Creates a template context from keys and values or merging in another value.
embedded
Embeds resources/views, resources/lang and public in the binary, so a release build runs from a single file:
migrations
Embeds the SQL migrations of a directory (default migrations, relative to the crate root) as &'static [renox::db::Migration].

Structs§

AnalyticsConfig
Google Search Console, Google Analytics 4 and Google Tag Manager, from GOOGLE_SITE_VERIFICATION, GA4_MEASUREMENT_ID, GA4_API_SECRET and GTM_CONTAINER_ID. Tags are added to pages only in production.
App
The application builder.
AppState
Shared state available to every handler through State<AppState>.
AuthUser
The logged-in user. Requests without one are sent to the login route (HTMX requests via HX-Redirect) or get 401 when they want JSON. Use Option<AuthUser> where logging in is optional.
Back
Redirects to the previous page (the Referer), or / when it’s unknown or on another site (so a link from elsewhere can’t use it as an open redirect).
ClientIp
The client’s IP address, when the server knows it: the connection’s address, or the one a trusted proxy forwarded.
Config
Application configuration, read from the process environment and .env.
Cookies
The app’s own cookies (the session has its own). Read them with the Cookies extractor; set them by returning a SetCookie with the response.
CurrentRoute
The route that answers this request, from a handler or middleware: its name (products.show) and path pattern (/products/{id}).
DomainParams
The parameters of the domain a request came to, for routes added with Routes::domain("{account}.example.com", …):
Download
Files sent as downloads: bytes made in the handler (a PDF, a CSV), a file on disk (streamed), a key in Storage, or any stream.
Embedded
Files from resources/views, resources/lang and public, as (relative path, contents). Built by renox::embedded!().
Errors
Validation errors: messages keyed by field name.
Found
The model a route parameter names, loaded from the database (Laravel’s route model binding), or a 404 page when there’s no such row.
Htmx
What HTMX told us about the current request.
HxPushUrl
Puts a URL in the browser’s address bar and history (HX-Push-Url), e.g. the filters of a list; HxPushUrl("false") keeps it as it is.
HxRedirect
Makes HTMX do a full page load of the given URL (HX-Redirect).
HxRefresh
Makes HTMX reload the whole page (HX-Refresh).
HxReswap
How HTMX swaps the response (HX-Reswap: innerHTML, outerHTML, beforeend, none…), overriding the request’s hx-swap.
HxRetarget
Makes HTMX swap the response into another element than the request’s hx-target (HX-Retarget), e.g. a form’s errors into a summary box.
HxTrigger
Triggers client-side events after the swap (HX-Trigger), e.g. (HxTrigger("product-saved".into()), view(...)).
Kernel
A booted application: its router, database, queue and maintenance commands.
KeyValues
Pairs of text in the order they were entered, like headers or settings: what the UI kit’s key_value field sends (meta[0][key], meta[0][value], …). Rows without a key are skipped, and a key entered twice keeps its last value.
Lang
The current request’s language and its texts.
Path
The route’s parameters (/orders/{id} → Path(id): Path<i64>), like axum’s Path, except that a value that doesn’t fit (/orders/abc, or an id too large) is a 404 page, as for a route that doesn’t exist, rather than a plain-text 400.
Provided
The app’s own shared values (an API client, a price list), available in handlers, jobs, listeners, commands and scheduled tasks.
Registry
Where the app and its modules register jobs, listeners, scheduled tasks and commands. Modules get it in Module::register.
RequestId
The request’s id: the X-Request-Id a proxy sent (when it looks safe: 8–64 letters, digits, ., _ or -), otherwise a new random one. It’s in every log line of the request, in the response’s X-Request-Id, and in error reports, so a visitor’s “request id” leads to the logs.
Resource
The handlers of a resource, for Routes::resource; leave out the actions it doesn’t have.
RouteInfo
One route as route:list shows it.
Routes
A module’s routes, with optional names for URL generation.
SentBroadcast
An event a test recorded instead of sending it to the open pages (TestApp::fake_broadcasts, AppState::broadcast).
SentNotification
A notification a test recorded instead of sending.
Session
The current visitor’s session, stored in an encrypted cookie.
SetCookie
A cookie to set, returned with the response: (SetCookie::new(…), view). By default it’s for the whole site (Path=/), not readable by JavaScript (HttpOnly), SameSite=Lax, Secure when APP_URL is https, and lasts until the browser closes (see max_age).
Toast
A toast; return it with the response. See the module docs.
ToastAction
A link or button in a toast (or a database notification): see Toast::action.
TrustedProxies
Proxies whose X-Forwarded-For and Forwarded headers are believed, from TRUSTED_PROXIES: addresses and CIDR ranges separated by commas, or * to believe whoever connects, for the last hop only.
Upload
A file posted in a multipart form.
Valid
Deserializes and validates a form (urlencoded or multipart with Upload fields), a JSON body, or the query string for GET, with the type’s Validate rules.
ValidationError
A failed validation. As a response it is 422 with {"message": ..., "errors": {...}}; for regular (non-HTMX, non-JSON) requests Renox turns it into a redirect back with the errors and old input flashed to the session.
Validator
Collects rule failures. Rules run in order and stop at a field’s first failure; rules other than required and accepted skip empty values.
View
A template response, rendered by Renox with the request’s globals: app (with the request’s app.locale), request, auth (auth.check, auth.user), t(), can(), flash, errors, error(), old(), csrf_token, csrf_field() and renox_head().

Enums§

CacheStore
Where the cache keeps its values, from CACHE_STORE.
CspMode
How strict the Content-Security-Policy header is, from CSP.
Environment
The environment the application runs in, from APP_ENV.
Error
The error type handlers return. Any anyhow-compatible error converts into Error::Internal with ?.
LogFormat
How log lines are written, from LOG_FORMAT.
SessionDriver
Where sessions live, from SESSION_DRIVER.
ToastKind
What a toast says about the outcome: its color, icon and whether it stays until dismissed (errors do: they need reading).

Constants§

ALPINE_VERSION
The version of the bundled Alpine.js.
CALLY_VERSION
The version of the bundled Cally (calendar web components, MIT).
CSRF_FIELD
The form field that carries the CSRF token.
CSRF_HEADER
The request header that carries the CSRF token (htmx and fetch requests).
HTMX_VERSION
The version of the bundled htmx.
METHOD_FIELD
The form field that overrides a POST’s method (PUT, PATCH or DELETE).
XSRF_COOKIE
The cookie that carries the CSRF token to JavaScript clients, with App::xsrf_cookie.
XSRF_HEADER
The header such clients send it back in (axios does it by itself).

Traits§

Module
A self-contained piece of an application: its routes and migrations, and later its jobs, policies and views.
Policy
Decides whether a user may perform an ability on a model.
RedirectExt
Named-route and intended-page redirects on axum’s Redirect (in the prelude):
Validate
Declares the rules for a form. Used by the Valid<T> extractor, which calls, in order: prepare, authorize, rules and, when they pass, after. Only rules is required.

Functions§

abort
An error with status and a message shown to the visitor, for return Err(abort(…)). See abort_if for a condition.
abort_if
Err(abort(status, message)) when condition holds, for ?.
abort_unless
Err(abort(status, message)) unless condition holds, for ?.
currency_decimals
The decimals a currency is usually written with: 2 for USD or AED, 0 for IDR or JPY. An amount in the smallest unit is divided by 10^decimals to give whole units (as the data grid’s money columns do).
format_money
amount in the currency code (ISO 4217), with its symbol, its usual decimals (or decimals) and the locale’s separators: Rp 75.000, $1,250.50, €1.250,50 in de (what the money template filter uses). An unknown code is written before the amount (CHF 12.00).
format_number
n with decimals decimals and the locale’s separators: 75.000 in id, 75,000 in en (what the number template filter uses).
generate_key
Generates a new APP_KEY value, e.g. base64:3q2+7w==....
random_token
A random, URL-safe token with 256 bits of entropy (43 characters), e.g. for an invitation link or an API key.
view
Renders name from the views directory with ctx (anything serializable, usually context! { ... }).

Type Aliases§

Result
The result type handlers return; Error by default.

Attribute Macros§

test
Marks an async test, like #[tokio::test], using the Tokio that Renox re-exports, so apps don’t need tokio as a dependency.

Derive Macros§

DbEnum
A fieldless enum stored as text: in the database (a TEXT column), in forms (<select>), in JSON and in templates. Variants are stored in snake_case (OnHold → on_hold) unless renamed with #[db(rename = "…")].
FromRow
Implements renox::db::FromRow, so sql(…).fetch_as::<T>() can read rows of any query (joins, aggregates, a few columns) into the struct.
Model
Implements renox::db::Model for a struct with named fields.
Validate
Implements renox::Validate from #[validate(…)] attributes on the fields, for forms that need only rules: