1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![forbid(unsafe_code)]
3#![deny(
4 clippy::dbg_macro,
5 missing_copy_implementations,
6 rustdoc::missing_crate_level_docs,
7 missing_debug_implementations,
8 missing_docs,
9 nonstandard_style,
10 unused_qualifications
11)]
12
13#[cfg(test)]
67#[doc = include_str!("../README.md")]
68mod readme {}
69
70mod assertions;
71
72mod test_transport;
73use std::{future::Future, process::Termination, sync::Arc};
74pub use test_transport::TestTransport;
75
76mod test_conn;
77pub use test_conn::TestConn;
78
79pub mod methods;
80pub mod prelude {
81 pub use crate::{
83 assert_body, assert_body_contains, assert_headers, assert_not_handled, assert_ok,
84 assert_response, assert_status, block_on, connector, init, methods::*,
85 };
86 pub use trillium::{Conn, Method, Status};
87}
88
89use trillium::{Handler, Info};
90pub use trillium::{Method, Status};
91use trillium_http::HttpContext;
92pub use url::Url;
93
94pub fn block_on<Fut: Future>(fut: Fut) -> Fut::Output {
96 runtime().block_on(fut)
97}
98
99pub async fn init(handler: &mut impl Handler) -> Arc<HttpContext> {
101 let mut info = Info::from(HttpContext::default());
102 info.insert_shared_state(runtime());
103 info.insert_shared_state(runtime().into());
104 handler.init(&mut info).await;
105 Arc::new(info.into())
106}
107
108pub use futures_lite::{self, AsyncRead, AsyncReadExt, AsyncWrite, Stream};
110
111mod server_connector;
112pub use server_connector::{ServerConnector, connector};
113use trillium_server_common::Config;
114pub use trillium_server_common::{
115 ArcedConnector, Connector, Runtime, RuntimeTrait, Server, ServerHandle,
116};
117
118#[cfg(unix)]
123#[doc(hidden)]
124pub trait QuicSocket: std::os::unix::io::AsFd {}
125#[cfg(unix)]
126impl<T: std::os::unix::io::AsFd> QuicSocket for T {}
127#[doc(hidden)]
128#[cfg(windows)]
129pub trait QuicSocket: std::os::windows::io::AsSocket {}
130#[cfg(windows)]
131impl<T: std::os::windows::io::AsSocket> QuicSocket for T {}
132
133cfg_if::cfg_if! {
134 if #[cfg(feature = "smol")] {
135 pub fn config() -> Config<impl Server<Runtime: Unpin, UdpTransport: QuicSocket>, ()> {
137 trillium_smol::config()
138 }
139
140 pub fn client_config() -> impl Connector<Runtime: Unpin, Udp: QuicSocket> {
142 trillium_smol::ClientConfig::default()
143 }
144 pub fn runtime() -> impl RuntimeTrait {
146 trillium_smol::SmolRuntime::default()
147 }
148 } else if #[cfg(feature = "async-std")] {
149 pub fn config() -> Config<impl Server<Runtime: Unpin, UdpTransport: QuicSocket>, ()> {
151 trillium_async_std::config()
152 }
153 pub fn client_config() -> impl Connector<Runtime: Unpin, Udp: QuicSocket> {
155 trillium_async_std::ClientConfig::default()
156 }
157 pub fn runtime() -> impl RuntimeTrait {
159 trillium_async_std::AsyncStdRuntime::default()
160 }
161 } else if #[cfg(feature = "tokio")] {
162 pub fn config() -> Config<impl Server<Runtime: Unpin, UdpTransport: QuicSocket>, ()> {
164 trillium_tokio::config()
165 }
166
167 pub fn client_config() -> impl Connector<Runtime: Unpin, Udp: QuicSocket> {
169 trillium_tokio::ClientConfig::default()
170 }
171
172 pub fn runtime() -> impl RuntimeTrait {
174 trillium_tokio::TokioRuntime::default()
175 }
176 } else {
177 pub fn config() -> Config<impl Server, ()> {
179 Config::<RuntimelessServer, ()>::new()
180 }
181
182 pub fn client_config() -> impl Connector {
184 RuntimelessClientConfig::default()
185 }
186
187 pub fn runtime() -> impl RuntimeTrait {
189 RuntimelessRuntime::default()
190 }
191 }
192}
193
194mod with_server;
195pub use with_server::{with_server, with_transport};
196
197mod test_server;
198pub use test_server::{ConnTest, TestServer};
199
200mod runtimeless;
201pub use runtimeless::{RuntimelessClientConfig, RuntimelessRuntime, RuntimelessServer};
202
203pub type TestResult = Result<(), Box<dyn std::error::Error>>;
205
206#[track_caller]
208pub fn harness<F, Fut, Output>(test: F) -> Output
209where
210 F: FnOnce() -> Fut,
211 Fut: Future<Output = Output>,
212 Output: Termination,
213{
214 let _ = env_logger::builder().is_test(true).try_init();
215 block_on(test())
216}
217
218#[track_caller]
220pub fn with_runtime<F, Fut, Output>(test: F) -> Output
221where
222 F: FnOnce(Runtime) -> Fut,
223 Fut: Future<Output = Output>,
224 Output: Termination,
225{
226 let runtime = runtime();
227 runtime.clone().block_on(test(runtime.into()))
228}
229
230pub use test_harness::test;
231
232mod http_test;
233#[doc(hidden)]
234pub use http_test::HttpTest;
235
236#[cfg(all(feature = "serde_json", feature = "sonic-rs"))]
237compile_error!("cargo features \"serde_json\" and \"sonic-rs\" are mutually exclusive");
238
239#[cfg(feature = "serde_json")]
240#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
241pub use serde_json::{Value, from_str as from_json_str, json, to_string as to_json_string};
242#[cfg(feature = "sonic-rs")]
243#[cfg_attr(docsrs, doc(cfg(feature = "sonic-rs")))]
244pub use sonic_rs::{Value, from_str as from_json_str, json, to_string as to_json_string};