rustango 0.8.0

A Django-inspired ORM + admin + multi-tenancy for Rust. One crate, opt in via features.
Documentation
[package]
name = "rustango"
description = "A Django-inspired ORM + admin + multi-tenancy for Rust. One crate, opt in via features."
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
keywords.workspace = true
categories.workspace = true
# Drop runnable demos + integration-test files from the published
# tarball. `src/admin/templates/` and `src/tenancy/{templates,static}/`
# stay — they're baked into the binary via include_str! / include_bytes!.
exclude = ["examples/", "tests/"]

[lints]
workspace = true

[features]
# Out of the box: ORM + auto-admin + Postgres + layered config +
# public forms framework. Opt in to multi-tenancy with
# `features = ["tenancy"]`. Drop `default-features` for the bare
# ORM (core + query + sql + migrate).
default = ["postgres", "admin", "config", "forms"]
postgres = ["sqlx/postgres"]

# Layered TOML config (`rustango::config`). Loads `config/default.toml`
# → `config/{env}.toml` → env-var overrides. Slice 8.3.
config = ["dep:toml"]

# Public forms framework (`rustango::forms`) — value parsing for HTML
# form payloads, shared between admin and user route handlers. Slice
# 8.4A ships the parsers; slice 8.4B added `#[derive(Form)]`. Slice
# 8.4C lights up CSRF protection behind the `csrf` sub-feature so
# parser-only users don't pay the cookie/rand cost.
forms = []

# CSRF protection (`rustango::forms::csrf`) — double-submit-cookie
# axum middleware. Lives behind its own flag so `forms`-only users
# (parsers without CSRF) don't pull cookie + rand + tower
# transitively.
csrf = ["forms", "dep:axum", "dep:base64", "dep:cookie", "dep:rand", "dep:tower"]

# Auto-admin HTTP layer (`rustango::admin`). Pulls in axum + Tera +
# the supporting middleware deps. Implies `forms` + `csrf` so the
# admin's CRUD handlers reuse the shared parsers and ship CSRF on
# every mutation by default.
admin = [
    "forms",
    "csrf",
    "dep:axum",
    "dep:tera",
    "dep:base64",
    "dep:http",
    "dep:http-body-util",
]

# Multi-tenancy module (`rustango::tenancy`). Implies `admin` (the
# tenant admin builder wraps `rustango::admin`). Pulls in Argon2 +
# HMAC-SHA256 + cookie + tower for the per-tenant + operator
# authentication paths.
tenancy = [
    "admin",
    "dep:async-trait",
    "dep:argon2",
    "dep:cookie",
    "dep:hmac",
    "dep:password-hash",
    "dep:rand",
    "dep:rpassword",
    "dep:serde_urlencoded",
    "dep:sha2",
    "dep:subtle",
    "dep:tokio",
    "dep:tower",
]

[dependencies]
# Proc-macros — separate by Rust language requirement.
rustango-macros = { version = "0.8.0", path = "../rustango-macros" }

# Always-on: core ORM + query layer + SQL writer + migration runner.
chrono     = { workspace = true }
indexmap   = { workspace = true }
inventory  = { workspace = true }
serde      = { workspace = true }
serde_json = { workspace = true }
sqlx       = { workspace = true }
thiserror  = { workspace = true }
tracing    = { workspace = true }
uuid       = { workspace = true }

# `config` feature dep — optional.
toml = { workspace = true, optional = true }

# `admin` feature deps — optional.
axum           = { workspace = true, optional = true }
base64         = { workspace = true, optional = true }
http           = { workspace = true, optional = true }
http-body-util = { workspace = true, optional = true }
tera           = { workspace = true, optional = true }

# `tenancy` feature deps — optional.
argon2           = { workspace = true, optional = true }
async-trait      = { workspace = true, optional = true }
cookie           = { workspace = true, optional = true }
hmac             = { workspace = true, optional = true }
password-hash    = { workspace = true, optional = true }
rand             = { workspace = true, optional = true }
rpassword        = { workspace = true, optional = true }
serde_urlencoded = { workspace = true, optional = true }
sha2             = { workspace = true, optional = true }
subtle           = { workspace = true, optional = true }
tokio            = { workspace = true, optional = true }
tower            = { workspace = true, optional = true }

[dev-dependencies]
tokio          = { workspace = true }
chrono         = { workspace = true }
uuid           = { workspace = true }
serde_json     = { workspace = true }
tower          = { workspace = true }
http-body-util = { workspace = true }
axum           = { workspace = true }
base64         = { workspace = true }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
dotenvy        = { workspace = true }

# Multi-file example demonstrating the Django-shape models / views /
# urls split for downstream user projects (slice 6c). Single-file
# examples are auto-detected by Cargo; multi-file ones need this
# explicit declaration.
[[example]]
name = "project_layout"
path = "examples/project_layout/main.rs"

[[example]]
name = "multitenant_demo"
path = "examples/multitenant_demo.rs"
required-features = ["tenancy"]

[[example]]
name = "tenancy_manage"
path = "examples/tenancy_manage.rs"
required-features = ["tenancy"]