trillium_testing/runtimeless/
server.rs1use super::SERVERS;
2use crate::{RuntimelessRuntime, TestTransport};
3use async_channel::Receiver;
4use std::io::{Error, Result};
5use trillium::Info;
6use trillium_server_common::Server;
7use url::Url;
8
9#[derive(Debug)]
11pub struct RuntimelessServer {
12 host: String,
13 port: u16,
14 channel: Receiver<TestTransport>,
15}
16
17impl RuntimelessServer {
18 pub fn is_empty() -> bool {
20 SERVERS.is_empty()
21 }
22
23 pub fn len() -> usize {
25 SERVERS.len()
26 }
27}
28
29impl Server for RuntimelessServer {
30 type Runtime = RuntimelessRuntime;
31 type Transport = TestTransport;
32 type UdpTransport = ();
33
34 fn runtime() -> Self::Runtime {
35 RuntimelessRuntime::default()
36 }
37
38 async fn accept(&mut self) -> Result<Self::Transport> {
39 self.channel.recv().await.map_err(Error::other)
40 }
41
42 fn from_host_and_port(host: &str, mut port: u16) -> Self {
43 if port == 0 {
44 loop {
45 port = fastrand::u16(..);
46 if !SERVERS.contains_key(&(host.to_string(), port)) {
47 break;
48 }
49 }
50 }
51
52 let entry = SERVERS
53 .entry((host.to_string(), port))
54 .or_insert_with(async_channel::unbounded);
55
56 let (_, channel) = entry.value();
57
58 Self {
59 host: host.to_string(),
60 channel: channel.clone(),
61 port,
62 }
63 }
64
65 async fn clean_up(self) {
66 SERVERS.remove(&(self.host, self.port));
67 }
68
69 fn init(&self, info: &mut Info) {
70 info.insert_shared_state(
71 Url::parse(&format!("http://{}:{}", &self.host, self.port)).unwrap(),
72 );
73 }
74}