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
//! The zero-plumbing bootstrap factory — `arcature::run()` (AP2.1-2).
//!
//! The golden path for an Arcature application should not require the
//! developer to repeat the same boilerplate every app writes: read the
//! bind port from the environment, fall back to the default, start from a
//! fresh `ApplicationBuilder<()>`. [`run`] does exactly that and returns
//! the partially-configured builder, so the application's bootstrap
//! shrinks to the subsystems + state it actually owns:
//!
//! ```ignore
//! use arcature::prelude::*;
//!
//! #[arcature::main]
//! async fn main() -> arcature::Result<()> {
//! arcature::run()
//! .routes(routes::routes())
//! .database(db_config)
//! .build()
//! .run_with_lifecycle(|resources| AppState::from_resources(resources))
//! .await
//! }
//! ```
//!
//! The factory is *not* a global, a singleton, or a runtime reflection
//! container — it is a plain function returning a fresh owned
//! [`ApplicationBuilder`] (AGENTS.md §20). It reads exactly one documented
//! environment variable (`ARCATURE_BACKEND_PORT`), the established dev
//! convention; it never reads subsystem URLs or secrets (those stay
//! explicit per AGENTS.md §21 — configuration is explicit and resolved).
//!
//! Expert users who want a different port source, bind address, or no
//! env read at all simply call [`Application::new`](crate::Application::new)
//! and set `.port()` / `.bind()` themselves — the builder remains the
//! full-configuration seam.
use crate;
/// The environment variable consulted by [`run`] for the bind port.
/// This is the established dev convention (`arc dev` sets it); production
/// deployments set it explicitly or fall back to the default.
pub const PORT_ENV: &str = "ARCATURE_BACKEND_PORT";
/// The zero-plumbing bootstrap factory.
///
/// Returns a fresh [`crate::ApplicationBuilder<()>`] configured with the
/// default bind address (`127.0.0.1`) and a port read from the
/// `ARCATURE_BACKEND_PORT` environment variable (default `3000`). The
/// application then adds its routes, subsystem configs, and state
/// closure and calls `.build().run_with_lifecycle(state_fn).await`.
///
/// This is additive — [`Application::new`](crate::Application::new)
/// remains the full-configuration seam for callers that want different
/// defaults. Reading the port env here is the single documented
/// convention; no other env variable is read, and no global state is
/// created (AGENTS.md §20/§21).
/// Resolves the bind port from `ARCATURE_BACKEND_PORT`, defaulting to
/// [`DEFAULT_PORT`] when unset or unparseable. Never panics — a malformed
/// value silently falls back to the default (the dev convention is a
/// plain integer; an operator who sets garbage gets the default, not a
/// crash on startup).