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