1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! # Actus
//!
//! The pragmatic web framework for Rust: auditable controllers, persistent
//! services, real HTTP — out of the box. Built directly on [hyper] and
//! [tokio]; there is no separate server to run it on.
//!
//! This crate is the façade you depend on. It re-exports the public API of the
//! implementation crates ([`actus-server`], [`actus-controller`],
//! [`actus-reply`]) and the two macros that declare your application's URL
//! surface. Add it with:
//!
//! ```toml
//! [dependencies]
//! actus = "1.0"
//! tokio = { version = "1", features = ["full"] }
//! serde_json = "1"
//! ```
//!
//! Optional features: `compression` (gzip/brotli responses), `websocket`
//! ([`ws::upgrade`]), and `openapi` (OpenAPI 3.x generation).
//!
//! # Quick start
//!
//! Two macros declare everything: `routes!` (one controller's API surface) and
//! `app_routes!` (the whole application's URL blueprint). A reviewer can see
//! every endpoint by reading just those two places.
//!
//! ```no_run
//! use actus::prelude::*;
//! use serde_json::json;
//!
//! // A controller owns a URL prefix and declares its routes in one block.
//! struct Greeter;
//!
//! #[controller]
//! impl Greeter {
//! routes! {
//! GET "" => index(),
//! GET "{name}" => greet(name: String),
//! }
//!
//! pub async fn index(&self) -> Reply {
//! reply!(json!({ "hello": "world" }))
//! }
//!
//! pub async fn greet(&self, name: String) -> Reply {
//! reply!(json!({ "hello": name }))
//! }
//! }
//!
//! // The application's URL blueprint, declared in one place. (The `deps`
//! // block — for injected services — is optional and omitted here.)
//! app_routes! {
//! routes {
//! "greet" => Greeter,
//! }
//! }
//!
//! // `init()` is generated by `app_routes!`; it builds the router.
//! #[tokio::main]
//! async fn main() -> actus::InitResult<()> {
//! let router = init().await?;
//! Server::new(router).run(3000).await?;
//! Ok(())
//! }
//! ```
//!
//! See the [`prelude`] for the common imports, and the repository's
//! `examples/` directory for auth, typed bodies, CORS, compression,
//! WebSockets, SSE, and middleware in working code.
//!
//! [hyper]: https://hyper.rs/
//! [tokio]: https://tokio.rs/
//! [`actus-server`]: https://docs.rs/actus-server
//! [`actus-controller`]: https://docs.rs/actus-controller
//! [`actus-reply`]: https://docs.rs/actus-reply
pub use Finalizer;
// Re-exported at the crate root so the `app_routes!` macro can resolve
// `::actus::Router` / `::actus::RouterBuilder` from generated code without
// requiring downstream crates to depend on `actus-server` directly.
pub use ;
/// WebSocket support — [`ws::upgrade`], [`ws::WebSocket`], [`ws::Message`].
/// Available with the `websocket` feature.
pub use websocket as ws;
/// OpenAPI 3.x doc generation — [`openapi::generate`], [`openapi::Options`].
/// Available with the `openapi` feature.
pub use openapi;
/// Error type used by `app_routes!`'s generated `init()` for startup-time
/// failures (DB connection refused, env var missing, migrations failing,
/// etc.). Aliased to `anyhow::Error` so any error implementing
/// `std::error::Error + Send + Sync + 'static` converts via `?`, and the
/// generated `init()` slots cleanly into an `anyhow::Result<()>` `main`.
pub type InitError = Error;
/// `Result<T, actus::InitError>`. The macro-generated `init()` returns this.
pub type InitResult<T> = Result;
/// Implementation re-exports used by the procedural macros.
///
/// This module exists so generated code can refer to types from the
/// implementation crates (`actus-controller`, etc.) via stable absolute paths
/// like `::actus::__internal::Verb`. End users should not import from here —
/// use [`prelude`] instead.
/// Common imports for Actus applications.