Skip to main content

ServiceBootstrap

Struct ServiceBootstrap 

Source
pub struct ServiceBootstrap { /* private fields */ }
Expand description

Builder for a microservice runtime.

use socle::{ServiceBootstrap, BootstrapCtx, Result};
use axum::{Router, routing::get};

ServiceBootstrap::new("my-service")
    .with_telemetry()
    .with_router(|_ctx: &BootstrapCtx| Router::new().route("/health", get(|| async { "ok" })))
    .serve("0.0.0.0:8080")
    .await

Implementations§

Source§

impl ServiceBootstrap

Source

pub fn new(service_name: impl Into<Arc<str>>) -> Self

Start a new bootstrap for a service.

Source

pub fn with_dotenv(self) -> Self

Load .env file if present. Call this before any with_* methods that read from environment variables.

Source

pub fn from_config( service_name: impl Into<Arc<str>>, cfg: BootstrapConfig, ) -> Result<Self>

Build from a BootstrapConfig.

Source

pub async fn run(self) -> Result<()>

Run using the bind address loaded from BootstrapConfig.

Source

pub fn with_body_limit(self, bytes: usize) -> Self

Override the maximum request body size in bytes. Defaults to 2 MiB.

Source

pub fn with_shutdown_timeout(self, timeout: Duration) -> Self

Hard deadline on graceful shutdown drain. Defaults to 30 seconds.

Source

pub fn with_shutdown_hook<F, Fut>( self, name: impl Into<String>, timeout: Duration, hook: F, ) -> Self
where F: Fn() -> Fut + Send + Sync + 'static, Fut: Future<Output = ()> + Send + 'static,

Register an async drain callback that runs after the HTTP server stops.

Source

pub fn with_readiness_check<F, Fut>( self, name: impl Into<String>, check: F, ) -> Self
where F: Fn() -> Fut + Send + Sync + 'static, Fut: Future<Output = HealthCheck> + Send + 'static,

Register a readiness check.

Source

pub fn with_health_probe(self, probe: impl HealthProbe + 'static) -> Self

Register a typed HealthProbe as a readiness check.

Source

pub fn with_version(self, version: impl Into<String>) -> Self

Override the version reported by the liveness endpoint.

Source

pub fn with_health_path(self, path: impl Into<String>) -> Self

Override the base path for health endpoints. Defaults to /health.

Source

pub fn with_telemetry(self) -> Self

Enable basic tracing via tracing_subscriber.

Source

pub fn with_telemetry_init<F>(self, f: F) -> Self
where F: FnOnce(&str) -> Result<()> + Send + 'static,

Override the telemetry initialisation function.

When set, called instead of the built-in tracing_subscriber setup. Use this to wire in a full OTel SDK (e.g. otel-bootstrap) from a wrapper crate without forking serve().

The callback receives the service name and must return Ok(()) on success or an Error that aborts startup.

Implies ServiceBootstrap::with_telemetry — no need to call both.

Prefer with_telemetry_provider for new code; it also handles shutdown (span/metric flush) automatically.

Source

pub fn with_telemetry_provider<P: TelemetryProvider>(self, provider: P) -> Self

Plug in a TelemetryProvider implementation.

The provider’s TelemetryProvider::init is called at startup and its TelemetryProvider::on_shutdown is registered as a drain hook that runs after the HTTP server stops (with a 30-second timeout).

Takes priority over with_telemetry_init and ServiceBootstrap::with_telemetry when all are called. Implies ServiceBootstrap::with_telemetry.

Use this to wire in otel-bootstrap or any other OTel SDK from a wrapper crate:

use socle::{ServiceBootstrap, ports::telemetry::TelemetryProvider, Result};

struct MyOtelProvider;
impl TelemetryProvider for MyOtelProvider {
    fn init(&self, _: &str) -> Result<()> { Ok(()) }
}

ServiceBootstrap::new("svc").with_telemetry_provider(MyOtelProvider);
Source

pub fn with_database(self, url: impl Into<String>) -> Self

Connect to a Postgres database and build a sqlx::PgPool.

Source

pub fn with_db_pool(self, pool: PgPool) -> Self

Provide a pre-built sqlx::PgPool instead of a connection URL.

Use this when the pool is constructed externally — for example by sqlx-switchboard’s PoolConfig — so that serve() skips its own pool construction. Takes precedence over ServiceBootstrap::with_database if both are called.

Source

pub fn with_migrations(self, migrator: Migrator) -> Self

Run sqlx migrations at startup.

Source

pub fn with_rate_limit(self, config: RateLimitBackend) -> Self

Enable the in-process GCRA rate limiter.

The limiter is applied as a tower layer inside serve(). By default it keys on the remote IP address — see with_rate_limit_extractor to change the extraction strategy.

Reverse-proxy note: the default RateLimitExtractor::Ip reads the L4 peer address, which is the proxy IP in production. All clients will share one rate-limit bucket. Use with_rate_limit_extractor(RateLimitExtractor::Header("x-forwarded-for")) when the service runs behind a trusted reverse proxy.

Memory note: the keyed limiter stores one entry per unique key with no TTL or size cap. Avoid RateLimitExtractor::Header with attacker-controlled headers in production; prefer Ip or a header with bounded cardinality.

Source

pub fn with_rate_limit_extractor(self, extractor: RateLimitExtractor) -> Self

Override the key extractor used by the rate limiter.

Source

pub fn with_rate_limit_provider<P: RateLimitProvider>(self, provider: P) -> Self

Plug in a RateLimitProvider implementation.

Takes priority over with_rate_limit when both are called. The provider receives the assembled router and returns it with the rate-limit tower layer applied.

Use this to inject distributed backends (Postgres, Redis, gossip) from a wrapper crate without calling with_layer directly:

use axum::Router;
use socle::{ServiceBootstrap, ports::rate_limit::RateLimitProvider};

struct MyDistributedRl;
impl RateLimitProvider for MyDistributedRl {
    fn apply(&self, router: Router) -> Router {
        router // .layer(my_distributed_rl_layer)
    }
}

ServiceBootstrap::new("svc").with_rate_limit_provider(MyDistributedRl);
Source

pub fn with_auth_provider<P: AuthProvider>(self, provider: P) -> Self

Plug in an AuthProvider implementation.

Groundwork ships no built-in auth backend — the provider is supplied by the caller (typically a wrapper crate such as service-kit) and owns its configuration, JWKS cache, API-key validator, etc.

The provider receives the assembled router (already wrapped by the rate-limit layer when one is configured) and returns it with the auth tower layer applied. Auth is applied after rate-limit so unauthenticated requests are still rate-counted, and before any extra layers registered via with_layer.

use axum::Router;
use socle::{ServiceBootstrap, ports::auth::AuthProvider};

struct MyJwtAuth;
impl AuthProvider for MyJwtAuth {
    fn apply(&self, router: Router) -> Router {
        router // .layer(my_auth_layer)
    }
}

ServiceBootstrap::new("svc").with_auth_provider(MyJwtAuth);
Source

pub fn with_audit_sink(self, sink: Arc<dyn AuditSink>) -> Self

Attach a pluggable audit sink.

When set, AuditLayer is applied after auth and before any with_layer extensions. Pass any type that implements AuditSink.

Source

pub fn with_audit_filter(self, filter: AuditFilter) -> Self

Override the default AuditFilter.

Has no effect unless with_audit_sink is also called.

Source

pub fn with_cors(self, cors: CorsLayer) -> Self

Override the default permissive CORS layer.

Source

pub fn with_cors_config(self, cfg: CorsConfig) -> Result<Self>

Configure CORS from a structured CorsConfig.

Source

pub fn with_router<F>(self, f: F) -> Self
where F: FnOnce(&BootstrapCtx) -> Router + Send + 'static,

Provide the router builder closure.

Source

pub fn with_layer<F>(self, f: F) -> Self
where F: FnOnce(Router) -> Router + Send + 'static,

Inject an arbitrary tower layer into the middleware stack.

Layers are applied in registration order, innermost first (i.e. the first call to with_layer wraps closest to the user router).

This is the primary extension point for wrapper crates. Example — adding the distributed-ratelimit layer from service-kit:

bootstrap.with_layer(|router| router.layer(my_distributed_rl_layer))
Source§

impl ServiceBootstrap

Source

pub async fn serve(self, addr: impl Into<String>) -> Result<()>

Run the service. Initialises every enabled integration in dependency order, binds the listener, serves until SIGINT/SIGTERM, then drains.

Source

pub async fn serve_with_shutdown( self, listener: TcpListener, shutdown: impl Future<Output = ()> + Send + 'static, ) -> Result<()>

Run the service using a pre-bound listener and a caller-supplied shutdown future. Useful for integration tests where you need to bind on port 0 and control when the server stops.

use axum::{Router, routing::get};
use socle::{BootstrapCtx, ServiceBootstrap};
use tokio::net::TcpListener;

ServiceBootstrap::new("my-service")
    .with_router(|_: &BootstrapCtx| Router::new().route("/", get(|| async { "ok" })))
    .serve_with_shutdown(listener, std::future::pending())
    .await
    .unwrap()

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Paint for T
where T: ?Sized,

Source§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
Source§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
Source§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
Source§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
Source§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling Attribute value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
Source§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
Source§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi Quirk value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
Source§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
Source§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1:

renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
Source§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the Condition value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ServiceExt for T

Source§

fn compression(self) -> Compression<Self>
where Self: Sized,

Compresses response bodies. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
Source§

fn set_request_id<M>( self, header_name: HeaderName, make_request_id: M, ) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension. Read more
Source§

fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension, using x-request-id as the header name. Read more
Source§

fn propagate_request_id( self, header_name: HeaderName, ) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses. Read more
Source§

fn propagate_x_request_id(self) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses, using x-request-id as the header name. Read more
Source§

fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>
where Self: Sized,

Catch panics and convert them into 500 Internal Server responses. Read more
Source§

fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>
where Self: Sized,

Intercept requests with over-sized payloads and convert them into 413 Payload Too Large responses. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,