proxima-lib 0.1.0

A sans-IO core where everything is a Pipe — one async In -> Result<Out, Err> trait worn four ways (transform, source, sink, observe), composed into proxies, gateways, caches, codecs and telemetry pipelines. Config-driven, runtime-agnostic: the same pipe runs on the from-scratch Prime per-core runtime, on tokio, or on no_std bare metal.
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
//! proxima is a sans-IO core where everything is a
//! [`Pipe`](crate::pipe::Pipe) — one async trait, `In -> Result<Out, Err>`.
//! Choose the types and the same trait becomes a **transform**
//! (`In -> Out`), a **source** (`() -> Out`), a **sink** (`In -> ()`), or an
//! **observe** (`In -> In`). There is no `Source` trait and no `Sink` trait;
//! those are the one trait with `()` on a side. Join pipes with `and_then`,
//! reach for the three primitives that wrap a pipe — filter, fan-out, fan-in
//! — and a proxy, a gateway, a cache, or a rate limiter falls out as those
//! composed rather than as another thing to learn.
//!
//! Because a pipe never touches I/O itself, the same pipe runs on the
//! from-scratch per-core [`prime`] runtime, on tokio, or on `no_std` bare
//! metal. Config and code are isomorphic: one spec drives the library, the
//! CLI, and an MCP control plane.
//!
//! For the teaching surface, start at the [`mod@pipe`] module — its
//! `//!` rustdoc is the canonical introduction to the algebra. Hot-swap,
//! recording, replay, and `causal explain` are not new machinery; each is
//! pipes composed — see [`Replay`], [`Diff`], [`Isolate`], [`Causal`],
//! [`SwappablePipe`], [`WriteBack`], [`check_determinism`].
//!
//! # Orientation
//!
//! Every wire proxima speaks — HTTP, gRPC, Kafka, MQTT, AMQP, DNS,
//! memcached, Redis, PostgreSQL — reduces to the same shape: a [`Listener`]
//! accepts connections and dispatches them to a [`Pipe`](crate::pipe::Pipe);
//! a [`Client`] dials an upstream and drives requests through one. Both sides are
//! fluent builders (this crate's "1st-class config AND 1st-class builder"
//! discipline — every builder also has a serialisable config mirror, see
//! e.g. [`listen::ListenTuningConfig`]). Bring the whole builder-sugar
//! surface into scope with one import:
//!
//! ```
//! use proxima::prelude::*;
//! ```
//!
//! A minimal service: a handler is a bare `async fn`, mounted with no
//! attribute at all (`App::mount` takes it directly); `.handle(pipe)` is
//! the listener-side twin.
//!
//! ```no_run
//! use proxima::prelude::*;
//! use proxima::{Request, Response, ProximaError};
//! use proxima::pipe::into_handle;
//! use bytes::Bytes;
//! use std::net::{Ipv4Addr, SocketAddr};
//!
//! struct Hello;
//! impl SendPipe for Hello {
//!     type In = Request<Bytes>;
//!     type Out = Response<Bytes>;
//!     type Err = ProximaError;
//!     async fn call(&self, _request: Request<Bytes>) -> Result<Response<Bytes>, ProximaError> {
//!         Ok(Response::ok("hello, proxima"))
//!     }
//! }
//! # use proxima::SendPipe;
//!
//! #[proxima::main]
//! async fn main() -> Result<(), ProximaError> {
//!     // Console logging in one call: RUST_LOG-filtered, ambient recorder
//!     // registered, drain already running — works with zero extra
//!     // features. `--features tracing-init` additionally bridges events
//!     // from the `tracing` crate itself; see `LogFormat`/`init_telemetry_with`
//!     // for JSON output.
//!     proxima::init_telemetry().expect("install console telemetry");
//!
//!     let bind = SocketAddr::from((Ipv4Addr::LOCALHOST, 8080));
//!
//!     // Listener: bind, pick the wire, hand it a pipe, serve until signalled.
//!     let server = Listener::http(bind).handle(into_handle(Hello)).serve().await?;
//!
//!     // Client: same axes (`.http()`/`.tls()`/`.kafka()`/…), the other direction.
//!     let client = Client::builder().http(format!("http://{bind}")).build()?;
//!     let body = client.get("/").send().await?.text().await?;
//!     assert_eq!(body, "hello, proxima");
//!
//!     server.run_until_signal().await;
//!     Ok(())
//! }
//! ```
//!
//! `examples/hello` is this same shape, runnable today
//! (`cargo run --example hello --features http1-native`). See
//! [`ListenerProtocolExt`]/[`ListenerTransportExt`] and
//! [`ClientProtocolExt`]/[`ClientTransportExt`]/[`ClientSecurityExt`] for
//! every wire and transport axis, and [`AnyProtocol`]/[`ClientProtocol`] for
//! how to teach either builder a protocol this crate has never heard of.

// `alloc` is referenced by the disciplined-component telemetry modules,
// which were originally no_std. brought in here so `alloc::vec::Vec`
// etc. resolve identically inside `crate::telemetry` regardless of
// whether the parent crate is std or no_std.
extern crate alloc;

#[cfg(test)]
extern crate self as proxima;

pub mod app;
pub mod app_builder;
pub mod app_config;
pub use proxima_core::buffer as buffer_pool;
// the no-runtime drive primitive; `proxima::runtime::block_on` is its
// runtime-holding sibling, and the `run*` edge drivers boot a runtime on top.
pub use proxima_primitives::block_on;
pub use proxima_primitives::pipe::body;
#[cfg(feature = "recording")]
pub use proxima_recording::pipe::causality;
pub mod client;
pub use proxima_codec as codec;
pub use proxima_codec::factory as codec_factory;
pub use proxima_config as config_format;
pub use proxima_patterns::control_plane;
pub use proxima_patterns::middleware::context_inject;
pub mod daemon_control_plane;
#[cfg(feature = "recording")]
pub mod determinism;
pub use proxima_core as error;
// mirrors proxima-http's own gate on `pub mod http1` (`any(http1,
// http1-native, http1-stream-client)`) — `http-prime-deps` is what forwards
// `http1-stream-client` here, and is on by default, so this stays reachable
// under default builds; a bare `--no-default-features` build has none of
// the three and correctly loses the module.
#[cfg(any(
    feature = "http1",
    feature = "http1-native",
    feature = "http-prime-deps"
))]
pub use proxima_http::http1::h1;
#[cfg(any(
    feature = "http1",
    feature = "http1-native",
    feature = "http-prime-deps"
))]
pub use proxima_http::http1::h1_body;
#[cfg(any(
    feature = "http1",
    feature = "http1-native",
    feature = "http-prime-deps"
))]
pub use proxima_http::http1::h1_connection;
#[cfg(any(
    feature = "http1",
    feature = "http1-native",
    feature = "http-prime-deps"
))]
pub use proxima_http::http1::h1_response;
#[cfg(feature = "http1")]
pub use proxima_http::http1::hyper_body;
#[cfg(feature = "tcp")]
pub use proxima_protocols::json_framing as framing;

// Composable, `Pipe`-shaped outbound HTTP/1.1 client — the production prime
// client path, usable as a transport STAGE in a pipe chain (e.g. a telemetry
// OTLP exporter terminal), not just the request-builder `Client` sugar. Pair
// `H1ClientUpstream` (a `Pipe`) with `PrimeTcpUpstream` (a `StreamUpstream`) and
// wrap via `pipe::into_handle` to get a `PipeHandle` to inject. Gated on
// `http-prime` (enables `proxima-h1/stream-client` + `proxima-net-prime`).
#[cfg(feature = "http-prime-deps")]
pub use proxima_http::http1::{
    H1ClientConfig, H1ClientUpstream, ResponseBodyMode, ResponseHandling, ResponseHandlingConfig,
    ResponseHeaderMode,
};
pub use proxima_listen as listen;
pub use proxima_patterns::kv;
// low-level serve-time plumbing (bind/spec/dispatch + per-core `run_with_runtime`;
// `Listener` itself lives here, see `listen_handle::Listener`). Named
// `listen_handle`, not `listener` — the bare `listener` name is this crate's
// own module (below), which composes this primitive into a fluent
// `Listener::builder()` surface via `ListenerBuilderEntry`, not a peer type.
pub use proxima_listen::handle as listen_handle;
pub mod listener;
#[cfg(all(
    feature = "http-prime-deps",
    any(target_os = "linux", target_os = "macos", target_os = "windows")
))]
pub use proxima_net::prime::PrimeTcpUpstream;
pub use proxima_primitives::pipe::header_list;
pub mod load;
pub use proxima_net::packet;
pub use proxima_primitives::pipe::path_pattern;
pub use proxima_primitives::pipe::routing as mount;
#[cfg(feature = "amqp-listener")]
pub use proxima_protocols::amqp;
#[cfg(feature = "dns-substrate")]
pub use proxima_protocols::dns;
#[cfg(feature = "grpc-framing")]
pub use proxima_protocols::grpc_framing as grpc;
#[cfg(feature = "kafka-listener")]
pub use proxima_protocols::kafka;
#[cfg(feature = "memcached-listener")]
pub use proxima_protocols::memcached;
#[cfg(feature = "mqtt-listener")]
pub use proxima_protocols::mqtt;
#[cfg(feature = "protobuf-wire")]
pub use proxima_protocols::protobuf_wire as protobuf;
pub use proxima_protocols::proxy_protocol;
#[cfg(feature = "websocket-frame")]
pub use proxima_protocols::websocket_frame;
pub use proxima_telemetry::log_buffer;
#[cfg(feature = "recording")]
pub mod recording;
pub use proxima_primitives::pipe::request;

pub mod runtime;
pub mod scenarios;
pub use proxima_config::schema;
pub use proxima_core::time;
#[cfg(feature = "http2")]
pub use proxima_http::http2 as h2;
#[cfg(feature = "http3")]
pub use proxima_http::http3 as h3;
pub use proxima_patterns::balancer::selection;
pub use proxima_primitives::pipe;
#[cfg(feature = "sync-wrappers")]
pub use proxima_primitives::sync;
pub use proxima_primitives::sync::shutdown;
pub use proxima_primitives::sync::task;
#[cfg(feature = "http3")]
pub use proxima_quic as quic;
pub mod server;
pub mod settings;
pub use proxima_config::store as state_store;
pub use proxima_config::sugar;
#[cfg(feature = "http1")]
pub use proxima_http::http1::shared_http;
pub use proxima_primitives::pipe::capture_surface;
pub use proxima_primitives::pipe::endpoint;
pub use proxima_primitives::pipe::swap_registry as swap;
pub use proxima_primitives::pipe::telemetry_surface;
pub use proxima_primitives::stream;
pub use proxima_telemetry as telemetry;
// OTLP exporter face: `OtlpClient::http().endpoint(..).build()` (and the config
// path `exporter_pipe`/`recorder_from_config`) lower to a prime `OtlpHttpCodec
// -> transport` pipe chain. lives here (not the leaf) because it needs an HTTP
// client in scope; transport is a builder verb, never a type name.
#[cfg(all(
    feature = "otlp-http",
    feature = "http-prime",
    any(target_os = "linux", target_os = "macos", target_os = "windows")
))]
pub mod otlp;
// mirrors proxima-http's own gate on `pub mod templates`
// (`any(http1, http1-stream-client)`); see the `h1` re-exports above.
#[cfg(any(feature = "http1", feature = "http-prime-deps"))]
pub use proxima_http::templates;
#[cfg(feature = "tls")]
pub use proxima_tls as tls;
pub mod tracing_init;
pub mod tutorial_doctests;
pub use proxima_patterns::balancer::upstream_ref;
pub use proxima_patterns::kv::write_back;
pub use proxima_primitives::pipe::pipe_factory;
pub use proxima_primitives::pipe::upgrade;
#[doc(hidden)]
pub use tutorial_doctests::tutorial_gate_prelude;

pub mod listeners;
pub mod middlewares;
// DAG-of-child-process-stages executor (`PipelineExecutor::run` fire-and-
// forgets each pipeline run via `tokio::spawn`) — a genuine tokio::process
// + tokio::spawn capability with no prime equivalent today, same as
// `scenarios::orchestrator`.
#[cfg(feature = "tokio")]
pub mod pipelines;
pub mod upstreams;
pub mod verify;

pub use app::{
    App, AppPipeBuilder, IntoMountTarget, MountTarget, RunConfig, Shutdown, offline_runtime,
};
#[cfg(feature = "recording")]
pub use causality::{ByteRange, Causal, CausalEdge, CausalIndex};
#[cfg(feature = "recording")]
pub use determinism::check_determinism;
#[cfg(feature = "rayon")]
pub use runtime::RayonBackgroundPool;
#[cfg(feature = "runtime-tokio")]
pub use runtime::TokioPerCoreRuntime;
pub use runtime::{BackgroundHandle, BackgroundPool, CoreId, Runtime};

/// The per-core runtime. See the [runtime discipline] doc for the why,
/// the [compatibility tradeoffs] doc for Tokio interop, and `PrimeRuntime::builder()`
/// or `PrimeConfig` for the entry points.
///
/// [runtime discipline]: https://github.com/brianbruggeman/proxima/blob/main/docs/runtime-prime/discipline.md
/// [compatibility tradeoffs]: https://github.com/brianbruggeman/proxima/blob/main/docs/runtime-prime/compat-mode-tradeoffs.md
#[cfg(all(
    feature = "runtime-prime-executor",
    feature = "runtime-prime-inbox-alloc",
    feature = "runtime-prime-reactor",
    feature = "runtime-prime-bgpool"
))]
pub mod prime {
    pub use crate::runtime::{BackgroundHandle, BackgroundPool, CoreId, Runtime, SpawnError};
    pub use prime::config::{Affinity, Builder, CoreSelection, PoolKind, PrimeConfig};
    pub use prime::os::runtime::PrimeRuntime;
}

/// `#[proxima::test]` attribute — one test attribute that drives the body on
/// proxima's prime runtime (tokio fallback) and subsumes `#[rstest]` +
/// cassette record/replay. `tests/e2e/proxima_test_smoke.rs` is the
/// worked example of every form it accepts.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::test;

/// `#[proxima::main]` attribute — the production sibling of `#[proxima::test]`.
/// Turns `async fn main() -> R` into a sync entry point that boots a runtime
/// and drives the body via `proxima::runtime::run*` (adaptive default —
/// prime when compiled, else tokio).
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::main;

/// `#[proxima::fixture]` — native rstest-style fixtures (no rstest dep),
/// consumed by `#[proxima::test]` parameters. `tests/e2e/proxima_test_smoke.rs`
/// exercises the plain, `once`, `from` and override forms.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::fixture;

/// `#[proxima::piped]` — generates a `Pipe`/`SendPipe`/`UnpinPipe`/
/// `UnpinSendPipe` impl from a plain function. See `proxima_macros::piped`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::piped;

/// `#[proxima::instrument]` — the unified observability annotation: one
/// attribute yields a trace span, its duration histogram (behind
/// `instrument-metrics`), and a log line, all from the same expansion. Use
/// this on a handler instead of hand-rolling any of the three. See
/// `proxima_macros::instrument`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::instrument;

/// `#[proxima::span]` — open a span without the metric/log framing
/// `#[proxima::instrument]` adds. See `proxima_macros::span`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::span;

/// `pipe!(closure)` — the function-like leaf-lift sibling of
/// `#[proxima::piped]`, for an expression position. The attribute macro is
/// named `piped` (not `pipe`) precisely so this bang macro can keep the bare
/// `pipe` identifier — Rust's macro namespace does not distinguish `#[pipe]`
/// from `pipe!(..)` by invocation syntax, so the two would still collide
/// (E0428) if both were exported under it. See `proxima_macros::pipe`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::pipe;

/// `filter!(predicate closure)` — lift a closure into the decision-pipe
/// shape (`In -> Result<In, Err>`) `pipe::filter`'s module doc describes.
/// See `proxima_macros::filter`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::filter;

/// `fanout!(a, b, ..)` — variadic `FanOut` builder over closure and/or
/// pipe-expression arms. See `proxima_macros::fanout`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::fanout;

/// `fanin!(a, b, ..)` — variadic `FanIn` builder over closure and/or
/// pipe-expression arms. See `proxima_macros::fanin`.
#[cfg(any(feature = "macros", test))]
pub use proxima_macros::fanin;

/// Runtime + cassette plumbing the `#[proxima::test]` expansion calls into.
#[cfg(any(test, feature = "test-support", feature = "macros"))]
pub mod test_support;

/// Cassette rot policy: rerecord/duplicate/staleness knobs + hooks.
#[cfg(any(test, feature = "test-support", feature = "macros"))]
pub mod cassette_config;

pub use app_builder::AppBuilder;
pub use body::{ChunkStream, RequestStream, ResponseStream};
pub use buffer_pool::{BufferPool, DEFAULT_BUFFER_BYTES, DEFAULT_POOL_PER_WORKER, PooledBuf};
pub use client::{
    Client, ClientBuilder, ClientProtocol, ClientProtocolExt, ClientSecurityExt,
    ClientTransportExt, FramedClient, RequestBuilder as ClientRequestBuilder,
    Response as ClientResponse,
};
pub use codec::{BytesPassthrough, FrameCodec, JsonCodec, MessageCodec, StatefulCodec, WireCodec};
pub use codec_factory::{
    BytesPassthroughCodecFactory, BytesPassthroughDynCodec, CodecBuildFuture, CodecFactory,
    CodecRegistry, DynCodec, DynCodecFactory, DynCodecHandle, JsonCodecFactory, JsonDynCodec,
};
pub use config_format::{
    ConfigFormatFactory, ConfigFormatRegistry, DynConfigFormatFactory, Json5ConfigFormat,
    JsonConfigFormat, RonConfigFormat, TomlConfigFormat, XmlConfigFormat, YamlConfigFormat,
    default_config_format_registry,
};
pub use control_plane::{
    ControlPlane, ControlPlanePipe, DynControlPlane, PipeState, PipeStatus, StaticControlPlane,
};
pub use daemon_control_plane::{DaemonControlPlane, PipeConfig};
pub use error::{ProximaError, ProximaResult};
// the entire public surface is Request<Bytes>/Response<Bytes>; re-export Bytes
// so callers don't need a direct `bytes` dep to write `Bytes::from_static`.
pub use bytes::Bytes;
pub use header_list::{HeaderList, IntoHeaderBytes};
pub use kv::{CacheEntry, EvictionPolicy, KvCaps, KvHandle};
pub use listen::{
    AnyProtocol, ClassifyOutcome, ListenProtocol, ListenProtocolFluent, ListenRegistry,
    ProbeVerdict, ServeBuilder, ServeContext, ThreadLocalListenProtocol, ThreadLocalListenRegistry,
};
pub use listen_handle::{Listener, ListenerHandle, ListenerSpec, ShutdownPolicy};
pub use listener::{
    ListenerBuilder, ListenerBuilderEntry, ListenerProtocolExt, ListenerTransportExt,
};
#[cfg(feature = "tokio")]
pub use listeners::McpListenProtocol;
#[cfg(any(feature = "http1", feature = "http1-native"))]
pub use listeners::{HttpListenProtocol, serve_h1_connection};
pub use load::{LoadContext, Spec, load};
pub use log_buffer::{DEFAULT_LOG_BUFFER_CAPACITY, LiveTailReceiver, LogBuffer, LogBufferRegistry};
pub use middlewares::auth::{Auth, AuthFactory};
pub use middlewares::diff::{Diff, diff_handle};
pub use middlewares::isolate::{Isolate, IsolateFactory};
pub use middlewares::rate_limit::{
    ExceededAction, KeyExtractor, KeyOf, RateLimit, RateLimitCaps, RateLimitFactory,
    TokenBucketConfig,
};
pub use middlewares::retry::{Retry, RetryBudget, RetryFactory, RetryPredicate};
pub use middlewares::transform::{RequestOp, ResponseOp, Transform, TransformFactory};
pub use middlewares::write_back::{WriteBack, WriteBackTarget};
pub use mount::{MethodFilter, Mount, Router};
pub use packet::{Packet, PacketListener, PacketListenerExt};
pub use path_pattern::PathPattern;
// `Handler`/`ThreadLocalHandler` are the served-Pipe rename (proxima-pipe
// TARGET 2): a blanket impl over `SendPipe<In=Request<Bytes>,
// Out=Response<Bytes>, Err=ProximaError>`, replacing the old `Pipe`/
// `ThreadLocalPipe` traits' `name()`/`background_tasks()` methods (deleted,
// see TARGET 3 — the mount-site label + `App::source` replace them). Callers
// that only bound on the trait (`fn f<H: Handler>`), never implemented it
// explicitly (the blanket now covers every qualifying `SendPipe`), name the
// served trait directly as `Handler`/`ThreadLocalHandler`; `impl Handler for
// X {}` sites were deleted at the source (redundant against the blanket, and
// a coherence conflict if kept).
pub use pipe::{
    Handler, PipeHandle, ThreadLocalHandler, ThreadLocalPipeHandle, into_handle,
    into_thread_local_handle,
};
pub use proxima_patterns::middleware::context_inject::ContextInjector;
pub use proxima_primitives::pipe::RoutingPipe;
pub use proxima_primitives::pipe::SendPipe;
#[cfg(feature = "recording")]
pub use recording::{
    AccumulatingSink, AppendFuture as RecordingAppendFuture, AppendLog, BinSource,
    BinSourceFactory, BoundedRecordingSink, CacheOutcome, DeferredRuntime, DropReason,
    DynRecordingSink, DynRecordingSource, DynRecordingSourceFactory, EventSource, EventTap,
    FailMode, FanOut, FormatKind, HttpEvent, INDEX_RECORD_BYTES, IndexReader, IndexRecord,
    IndexWriter, InteractionId, JsonlSource, JsonlSourceFactory, LazyFanOut, PipelineEvent,
    PipelineOutcome, ProcessEvent, ProtocolEvent, RECORD_DROP_METRIC, RECORDING_FORMAT_VERSION,
    RecordMeta, RecordingEvent, RecordingEventStream, RecordingSink, RecordingSource,
    RecordingSourceFactory, RecordingSourceRegistry, ReplayLog,
    RequestHeader as RecordingRequestHeader, SinkSpec, SourceBuildFuture, TerminalSignal,
    deferred_runtime,
};
pub use request::{Request, RequestBuilder, RequestContext, Response};
pub use scenarios::{
    CompareOp, Expectation, OrchestrationMode, Scenario, ScenarioPipeSpec, WorkloadSpec,
};
#[cfg(feature = "tokio")]
pub use scenarios::{ScenarioReport, run_scenario};
pub use schema::{
    EmptyResolver, EnumVariant, FieldFlags, PathSegment, Schema, SchemaRegistry, SchemaResolver,
    StringFormat, StructField, ValidationError,
};
pub use selection::{
    DispatchOutcome, DynSelection, Fallthrough, LeastConn, MissPolicy, MissReason, RoundRobin,
    Selection, SelectionHandle, ThreadLocalDynSelection, ThreadLocalSelection,
    ThreadLocalSelectionHandle, WeightedLeastConn, WeightedRoundRobin,
};
pub use swap::{SwapRegistry, SwappablePipe};

pub use pipe_factory::{DynPipeFactory, PipeFactory, PipeFactoryRegistry};
#[cfg(feature = "tokio")]
pub use pipelines::{
    DynPipelineControlPlane, FsPipelineControlPlane, InMemoryPipelineControlPlane,
    PipelineControlPlane, PipelineControlPlanePipe, PipelineExecutor, PipelineRunReport,
    PipelineSpec, PipelineStatus, PipelineSubmission, PipelineSummary, StageReport, StageSpec,
};
pub use settings::{BearerAuth, ClientAuth, Composable, HttpListener, HttpUpstream, OauthAuth};
#[cfg(feature = "http1")]
pub use shared_http::{SharedHttpClient, SharedHyperClient};
pub use stream::{
    Accept, BindAddr, Connect, PeerInfo, StreamConnection, StreamListener, StreamListenerExt,
    StreamUpstream, StreamUpstreamExt,
};
pub use sugar::desugar;
// the fluent builder base seam. The axis sugar itself is TYPE-SPECIFIC, not
// blanket-impl'd over this: `use proxima::{ListenerTransportExt,
// ListenerProtocolExt}` / `{ClientTransportExt, ClientSecurityExt,
// ClientProtocolExt}` light up `.tcp()`/`.http()`/… on `ListenerBuilder` /
// `ClientBuilder` respectively.
pub use proxima_primitives::transport;
pub use proxima_primitives::transport::{
    DEFAULT_REPLAY_CAP_BYTES, Replay, ReplayEvent, tap_complete, tap_complete_with_size,
};
pub use sugar::SpecBuilder;
pub use telemetry::{
    HistogramSummary, Labels, Metrics, MetricsSnapshot, NoopTelemetry, Telemetry, TelemetryHandle,
};
#[cfg(any(feature = "http1", feature = "http-prime-deps"))]
pub use templates::{TemplateContext, expand as expand_template};
// init_tracing_default is #[deprecated] in favor of init_telemetry_with;
// re-exporting it here is not a new call site, so silence the lint here
// rather than at every downstream caller.
#[allow(deprecated)]
pub use tracing_init::{LogFormat, init_tracing, init_tracing_default};
pub use tracing_init::{init_telemetry, init_telemetry_with};
pub use upgrade::{
    HijackStream, HijackedSocket, LocalHijackStream, LocalHijackedSocket, LocalUpgradeFuture,
    LocalUpgradeHandler, UpgradeFuture, UpgradeHandler,
};
pub use upstream_ref::{
    CallTracker, OutlierPolicy, ThreadLocalUpstreamRef, UpstreamMetrics, UpstreamRef,
};
pub use upstreams::{
    CallbackFn, CallbackFuture, CallbackPipeFactory, CallbackRegistry, CallbackUpstream,
    DynCallbackFn, KvCache, KvCacheFactory, KvFile, KvFileFactory, SynthPipeFactory, SynthUpstream,
};
#[cfg(feature = "tokio")]
pub use upstreams::{
    ProcessPipeFactory, ProcessSpec, ProcessUpstream, ReadyProbe, RestartPolicy, ShutdownSignal,
};
#[cfg(unix)]
pub use upstreams::{ProcessRpcPipeFactory, ProcessRpcSpec, ProcessRpcUpstream};
#[cfg(feature = "recording")]
pub use upstreams::{RecordPipeFactory, RecordUpstream, ReplayPipeFactory, ReplayUpstream};
pub use write_back::{WriteBackConditions, WriteBackRule};

/// The one import for both halves of the builder-sugar surface:
///
/// - Everything a THIRD-PARTY crate needs to plug a custom protocol into
///   proxima without depending on `proxima-listen` directly: the two open
///   extension traits — [`AnyProtocol`] for
///   `Listener::builder().any().protocol(impl AnyProtocol)`, [`ClientProtocol`]
///   for `Client::builder().protocol(impl ClientProtocol)` — the builder entry
///   points those methods live on, and the verdict/outcome types an
///   `AnyProtocol::probe` impl returns and a caller inspecting
///   `Classifier::advance` reads. Mirrors the two seams
///   `src/client/handle.rs`'s `ClientProtocol` doc and
///   `src/listener/handle.rs`'s `ListenerBuilder::protocol` doc describe.
/// - The TYPE-SPECIFIC builder-sugar extension traits themselves —
///   [`ListenerTransportExt`] / [`ListenerProtocolExt`] for `ListenerBuilder`,
///   [`ClientTransportExt`] / [`ClientSecurityExt`] / [`ClientProtocolExt`]
///   for `ClientBuilder` — so `.tcp()`/`.http()`/`.tls()`/`.kafka()`/… are all
///   in scope from this one `use`.
///
/// One `use` unlocks every axis method in the same chain — no separate
/// import per trait:
///
/// ```
/// use proxima::prelude::*;
///
/// let client = Client::builder()
///     .https("https://localhost:8443") // ClientProtocolExt
///     .tls()                           // ClientSecurityExt
///     .tcp()                           // ClientTransportExt
///     .build()?;
/// # Ok::<(), proxima::ProximaError>(())
/// ```
pub mod prelude {
    pub use crate::{
        AnyProtocol, App, ClassifyOutcome, Client, ClientBuilder, ClientProtocol,
        ClientProtocolExt, ClientSecurityExt, ClientTransportExt, Listener, ListenerBuilder,
        ListenerBuilderEntry, ListenerProtocolExt, ListenerTransportExt, ProbeVerdict,
    };
}

/// Drive a future to completion — expression sugar over the `block_on` verb.
/// Two arities, both pointing down to a concrete `block_on`:
/// - `block_on!(fut)` — the no-runtime [`block_on`](crate::block_on()) poll loop
///   (drives on the calling thread, no runtime, no reactor).
/// - `block_on!(rt, fut)` — the runtime-holding
///   [`block_on`](crate::runtime::block_on): drives `fut` on core 0 of the
///   runtime `rt` you already HOLD (foreign-thread entry — see its doc).
///
/// `run!` is the sibling that BOOTS a runtime first. Reach for `block_on!`
/// when you already hold a runtime (or need none); reach for `run!` at an edge.
#[macro_export]
macro_rules! block_on {
    ($rt:expr, $fut:expr) => {
        $crate::runtime::block_on(&$rt, $fut)
    };
    ($fut:expr) => {
        $crate::block_on($fut)
    };
}

/// Boot a runtime, then drive `fut` to completion on it — expression sugar for
/// the edge `run*` drivers (`#[proxima::main]` is the attribute form). Every
/// arm points down to a `crate::runtime::run*` driver:
/// - `run!(fut)` — adaptive [`run`](crate::runtime::run) (prime when compiled,
///   else tokio).
/// - `run!(prime, fut)` — [`run_prime`](crate::runtime::run_prime).
/// - `run!(tokio, fut)` — `crate::runtime::run_tokio` (feature-gated behind
///   `tokio`), the multi-thread tokio drive the adaptive path falls back to.
#[macro_export]
macro_rules! run {
    (prime, $fut:expr) => {
        $crate::runtime::run_prime($fut)
    };
    (tokio, $fut:expr) => {
        $crate::runtime::run_tokio(true, ::core::option::Option::None, $fut)
    };
    ($fut:expr) => {
        $crate::runtime::run($fut)
    };
}

#[cfg(test)]
#[allow(clippy::disallowed_methods, clippy::unwrap_used, clippy::expect_used)]
mod drive_macro_tests {
    #[test]
    fn block_on_bang_no_runtime_drives_to_completion() {
        let output: u32 = crate::block_on!(async { 40 + 2 });
        assert_eq!(output, 42);
    }

    #[test]
    fn run_bang_adaptive_boots_and_drives() {
        let output = crate::run!(async { 40 + 2 }).expect("adaptive run drives the body");
        assert_eq!(output, 42);
    }

    #[cfg(feature = "tokio")]
    #[test]
    fn run_bang_tokio_arm_boots_and_drives() {
        let output = crate::run!(tokio, async { 40 + 2 }).expect("tokio run drives the body");
        assert_eq!(output, 42);
    }

    #[cfg(all(
        feature = "runtime-prime-executor",
        feature = "runtime-prime-inbox-alloc",
        feature = "runtime-prime-reactor",
        feature = "runtime-prime-bgpool"
    ))]
    #[test]
    fn run_bang_prime_arm_boots_and_drives() {
        let output = crate::run!(prime, async { 40 + 2 }).expect("prime run drives the body");
        assert_eq!(output, 42);
    }

    #[cfg(all(
        feature = "runtime-prime-executor",
        feature = "runtime-prime-inbox-alloc",
        feature = "runtime-prime-reactor",
        feature = "runtime-prime-bgpool"
    ))]
    #[test]
    fn block_on_bang_runtime_arm_drives_on_held_runtime() {
        let runtime = crate::runtime::PrimeRuntime::new(1).expect("build a one-core prime runtime");
        let output = crate::block_on!(runtime, async { 40 + 2 })
            .expect("block_on drives the body on the held runtime");
        assert_eq!(output, 42);
    }
}