Skip to main content

webx/
lib.rs

1//! Umbrella crate for the rust-webx framework (package `rust-webx`, imported as
2//! `webx`).
3//!
4//! Re-exports the whole framework so applications need a single dependency:
5//!
6//! ```toml
7//! [dependencies]
8//! rust-webx = "0.5"
9//! ```
10//!
11//! ```ignore
12//! use webx::*;
13//! ```
14//!
15//! The dependency name is `rust-webx`; the import name is `webx`. The same
16//! applies to the sub-crates (`rust-webx-core` → `webx_core`,
17//! `rust-webx-host` → `webx_host`, `rust-webx-macros` → `webx_macros`,
18//! `rust-webx-spa` → `webx_spa`, `rust-webx-openapi` → `webx_openapi`).
19
20// --- Core traits ---
21pub use webx_core::app::IHost;
22pub use webx_core::auth::{
23    IAuthenticationHandler, IAuthorizationPolicy, IClaims, IDynamicAuthorizer,
24};
25pub use webx_core::cache::{
26    cache_ext::DistributedCacheExtensions,
27    options::DistributedCacheEntryOptions,
28    trait_def::{CacheError, IDistributedCache},
29};
30pub use webx_core::config::{
31    bind_config, bind_root, load_appsettings, AppOptions, AppSection, CorsSection, IAppOptions,
32    JwtSection, MetricsSection, RateLimitSection, TlsSection,
33};
34pub use webx_core::dispatch_runtime::{dispatch_provider, DispatchRuntime};
35pub use webx_core::error::{Error, Result};
36pub use webx_core::form::{
37    sanitize_file_name, set_spool_root, spool_root, FormDeserializer, FormError, FormField,
38    FormFile, FormFileBuilder, MultipartForm, SPOOL_FILE_PREFIX,
39};
40pub use webx_core::handler::{IClaimsCarrier, IEventHandler, IHostedService, IRequestHandler};
41pub use webx_core::http::{
42    content_disposition_value, read_json_body, write_json_response, ByteRange, Disposition,
43    FileBody, FileSource, FromHttpContext, HttpStatus, IClaimsExt, IHttpContext, IHttpRequest,
44    IHttpResponse, Json, ResponseBody, SeekableReader, STREAM_BUF_SIZE,
45};
46pub use webx_core::mediator::build_pipeline_chain;
47pub use webx_core::mediator::{IEventRequest, IMediator, IRequest};
48pub use webx_core::middleware::IMiddleware;
49pub use webx_core::mode::AppMode;
50pub use webx_core::pagination::{PagedRequest, PagedResponse};
51pub use webx_core::paths::{
52    app_base, framework_root, looks_like_app_base, looks_like_framework_root,
53};
54pub use webx_core::pipeline::{BoxedNextFn, BoxedPipelineFuture, IPipelineBehavior};
55pub use webx_core::problem::{FieldError, ProblemDetails};
56pub use webx_core::request_context::RequestContext;
57pub use webx_core::route::diagnostics::{
58    duplicate_handlers, format_route_diagnostics, orphan_handlers, orphan_route_details,
59    orphan_routes, route_snapshots,
60};
61pub use webx_core::routing::{HttpMethod, IEndpoint, IRouter, RouteMeta};
62
63// --- DI extensions ---
64pub use webx_core::route::bind::bind_form_request;
65pub use webx_core::route::ext::{is_mediator_active, should_scan_endpoints, IServiceCollectionExt};
66pub use webx_core::route::params::try_deserialize_from_params;
67#[allow(deprecated)]
68pub use webx_core::route::scan::{
69    global_provider, set_global_provider, HandlerCache, HandlerEntry, HandlerRegistration,
70    HandlerRegistry, ParamMeta, RequestParamEntry, ResponseData, RouteDispatch, RouteDispatchFn,
71    RouteEntry,
72};
73
74// --- HTTP layer ---
75pub use webx_host::auth_jwt::{init_jwt_secret, jwt_middleware, jwt_secret, JwtAuth, JwtClaims};
76pub use webx_host::authz::{
77    build_resource_policy_from_routes, collect_authorizers, resource_auth_middleware,
78    AuthorizerSet, ResourceAuthorization,
79};
80pub use webx_host::compression::{compress_gzip, CompressionConfig, CompressionMiddleware};
81pub use webx_host::context::{HttpContext, HttpRequest, HttpResponse};
82pub use webx_host::cors::{CorsConfig, CorsMiddleware};
83pub use webx_host::diagnostics::log_startup_diagnostics;
84pub use webx_host::endpoint::{
85    ControllerEndpoint, RequestEndpoint, StaticHtmlEndpoint, StaticJsonEndpoint,
86};
87pub use webx_host::health::{HealthCheckEntry, HealthCheckFn, HealthCheckRegistry, HealthStatus};
88pub use webx_host::memory_cache::MemoryCache;
89pub use webx_host::pipeline::{HandlerFn, MiddlewarePipeline};
90pub use webx_host::rate_limit::{RateLimitMiddleware, RateLimiter};
91pub use webx_host::request_id::RequestIdMiddleware;
92pub use webx_host::request_tracing::RequestTracing;
93pub use webx_host::router::Router;
94pub use webx_host::security_headers::SecurityHeadersMiddleware;
95pub use webx_host::server::{Host, HostAppBuilder, HostBuilder, Server, ServerHandle};
96#[cfg(feature = "testing")]
97pub use webx_host::testing::{free_port, spawn, spawn_with_health, wait_until_ready, TestServer};
98pub use webx_host::timing::TimingMiddleware;
99
100// --- Mediator ---
101pub use webx_core::mediator::Mediator;
102
103// --- Web (SPA) ---
104pub use webx_spa::SpaMiddleware;
105
106/// Static file hosting, including files compiled into the executable.
107///
108/// ```ignore
109/// // build.rs: webx::builder().web_root("wwwroot").build()
110/// #[webx::main(embed)]
111/// async fn main() {
112///     Host::builder().use_spa("wwwroot").build()
113/// }
114/// ```
115pub mod spa {
116    pub use webx_spa::{
117        embed_assets, inventory, ContentEncoding, EmbeddedAsset, EmbeddedAssets, SpaMiddleware,
118        SpaSource, EMBED_ENV,
119    };
120}
121
122/// Files compiled into the executable by `#[webx::main(embed)]`, read by path.
123///
124/// ```ignore
125/// let config = webx::assets::read_str("config/default.json");
126/// ```
127pub mod assets {
128    pub use webx_spa::assets::{read, read_str};
129}
130
131// --- OpenAPI ---
132pub use webx_openapi::{generate_openapi_spec, APIUI_HTML};
133
134// --- Macros ---
135pub use webx_macros::{
136    authorize, claims, delete, embed_assets, endpoint, get, handler, main, post, put,
137    WebxRequestMeta,
138};
139
140// --- Re-export rust_dix (for manual registration, #[inject] auto-registration, and module blocks) ---
141pub use rust_dix;
142pub use rust_dix::inject;
143pub use rust_dix::ScopeFactory;
144pub use rust_dix_macros;
145pub use rust_dix_macros::{module, Inject};
146
147// --- Re-export common dependencies ---
148pub use async_trait::async_trait;
149pub use hyper;
150pub use serde;
151pub use serde_json;
152pub use tokio;
153
154// =========================================================================
155// Convenience macro: register_handlers!
156//
157// **Deprecated for HTTP handlers.** HTTP dispatch uses inventory +
158// `HandlerCache` exclusively (`#[handler]` / `#[handler(inject)]`).
159// Keep this macro only for non-HTTP Mediator use or manual DI registration.
160//
161// Generates chained .singleton() calls for handlers that implement Default.
162//
163// Usage inside register():
164//   .register(|svc| {
165//       register_handlers!(svc,
166//           HelloRequest => String => HelloHandler,
167//           DeleteUserRequest => () => DeleteUserHandler,
168//       )
169//   })
170// =========================================================================
171#[deprecated(
172    since = "0.2.0",
173    note = "HTTP handlers should use `#[handler]` / `#[handler(inject)]` (inventory). \
174            register_handlers! remains for non-HTTP Mediator scenarios only."
175)]
176#[macro_export]
177macro_rules! register_handlers {
178    ($svc:ident, $($req:ty => $rsp:ty => $handler:ty),+ $(,)?) => {
179        $svc
180        $(
181            .singleton::<dyn $crate::IRequestHandler<$req, $rsp>>(
182                |_| ::std::sync::Arc::new(<$handler>::default())
183            )
184        )+
185    };
186}