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::ServerConfig;
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<ServerConfig> {
101 let mut info = Info::from(ServerConfig::default());
102 info.insert_state(runtime());
103 info.insert_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
118cfg_if::cfg_if! {
119 if #[cfg(feature = "smol")] {
120 pub fn config() -> Config<impl Server, ()> {
122 trillium_smol::config()
123 }
124
125 pub fn client_config() -> impl Connector {
127 trillium_smol::ClientConfig::default()
128 }
129 pub fn runtime() -> impl RuntimeTrait {
131 trillium_smol::SmolRuntime::default()
132 }
133 } else if #[cfg(feature = "async-std")] {
134 pub fn config() -> Config<impl Server, ()> {
136 trillium_async_std::config()
137 }
138 pub fn client_config() -> impl Connector {
140 trillium_async_std::ClientConfig::default()
141 }
142 pub fn runtime() -> impl RuntimeTrait {
144 trillium_async_std::AsyncStdRuntime::default()
145 }
146 } else if #[cfg(feature = "tokio")] {
147 pub fn config() -> Config<impl Server, ()> {
149 trillium_tokio::config()
150 }
151
152 pub fn client_config() -> impl Connector {
154 trillium_tokio::ClientConfig::default()
155 }
156
157 pub fn runtime() -> impl RuntimeTrait {
159 trillium_tokio::TokioRuntime::default()
160 }
161 } else {
162 pub fn config() -> Config<impl Server, ()> {
164 Config::<RuntimelessServer, ()>::new()
165 }
166
167 pub fn client_config() -> impl Connector {
169 RuntimelessClientConfig::default()
170 }
171
172 pub fn runtime() -> impl RuntimeTrait {
174 RuntimelessRuntime::default()
175 }
176 }
177}
178
179mod with_server;
180pub use with_server::{with_server, with_transport};
181
182mod test_server;
183pub use test_server::{ConnTest, TestServer};
184
185mod runtimeless;
186pub use runtimeless::{RuntimelessClientConfig, RuntimelessRuntime, RuntimelessServer};
187
188pub type TestResult = Result<(), Box<dyn std::error::Error>>;
190
191#[track_caller]
193pub fn harness<F, Fut, Output>(test: F) -> Output
194where
195 F: FnOnce() -> Fut,
196 Fut: Future<Output = Output>,
197 Output: Termination,
198{
199 let _ = env_logger::builder().is_test(true).try_init();
200 block_on(test())
201}
202
203#[track_caller]
205pub fn with_runtime<F, Fut, Output>(test: F) -> Output
206where
207 F: FnOnce(Runtime) -> Fut,
208 Fut: Future<Output = Output>,
209 Output: Termination,
210{
211 let runtime = runtime();
212 runtime.clone().block_on(test(runtime.into()))
213}
214
215pub use test_harness::test;
216
217mod http_test;
218#[doc(hidden)]
219pub use http_test::HttpTest;
220
221#[cfg(all(feature = "serde_json", feature = "sonic-rs"))]
222compile_error!("cargo features \"serde_json\" and \"sonic-rs\" are mutually exclusive");
223
224#[cfg(feature = "serde_json")]
225#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
226pub use serde_json::{Value, from_str as from_json_str, json, to_string as to_json_string};
227#[cfg(feature = "sonic-rs")]
228#[cfg_attr(docsrs, doc(cfg(feature = "sonic-rs")))]
229pub use sonic_rs::{Value, from_str as from_json_str, json, to_string as to_json_string};