1#![allow(clippy::cargo_common_metadata)]
2
3use lune_utils::TableBuilder;
4use mlua::prelude::*;
5
6pub(crate) mod body;
7pub(crate) mod client;
8pub(crate) mod server;
9pub(crate) mod shared;
10pub(crate) mod url;
11
12use crate::shared::{hyper::HyperExecutor, tcp::Tcp};
13
14use self::{
15 client::{stream::WsStream, tcp::TcpConfig},
16 server::config::ServeConfig,
17 shared::{request::Request, response::Response, websocket::Websocket},
18};
19
20pub use self::client::fetch;
21
22const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/types.d.luau"));
23
24#[must_use]
28pub fn typedefs() -> String {
29 TYPEDEFS.to_string()
30}
31
32pub fn module(lua: Lua) -> LuaResult<LuaTable> {
40 HyperExecutor::attach(&lua);
41
42 let submodule_http = TableBuilder::new(lua.clone())?
43 .with_async_function("request", net_http_request)?
44 .with_async_function("serve", net_http_serve)?
45 .build_readonly()?;
46
47 let submodule_tcp = TableBuilder::new(lua.clone())?
48 .with_async_function("connect", net_tcp_connect)?
49 .build_readonly()?;
50
51 let submodule_ws = TableBuilder::new(lua.clone())?
52 .with_async_function("connect", net_ws_connect)?
53 .build_readonly()?;
54
55 TableBuilder::new(lua)?
56 .with_async_function("request", net_http_request)?
57 .with_async_function("socket", net_ws_connect)?
58 .with_async_function("serve", net_http_serve)?
59 .with_function("urlEncode", net_url_encode)?
60 .with_function("urlDecode", net_url_decode)?
61 .with_value("http", submodule_http)?
62 .with_value("tcp", submodule_tcp)?
63 .with_value("ws", submodule_ws)?
64 .build_readonly()
65}
66
67async fn net_http_request(lua: Lua, req: Request) -> LuaResult<Response> {
68 self::client::send(req, lua).await
69}
70
71async fn net_http_serve(lua: Lua, (port, config): (u16, ServeConfig)) -> LuaResult<LuaTable> {
72 self::server::serve(lua.clone(), port, config)
73 .await?
74 .into_lua_table(lua)
75}
76
77async fn net_tcp_connect(_: Lua, (host, port, config): (String, u16, TcpConfig)) -> LuaResult<Tcp> {
78 self::client::connect_tcp(host, port, config).await
79}
80
81async fn net_ws_connect(_: Lua, url: String) -> LuaResult<Websocket<WsStream>> {
82 let url = url.parse().into_lua_err()?;
83 self::client::connect_ws(url).await
84}
85
86fn net_url_encode(
87 lua: &Lua,
88 (lua_string, as_binary): (LuaString, Option<bool>),
89) -> LuaResult<LuaString> {
90 let as_binary = as_binary.unwrap_or_default();
91 let bytes = self::url::encode(lua_string, as_binary)?;
92 lua.create_string(bytes)
93}
94
95fn net_url_decode(
96 lua: &Lua,
97 (lua_string, as_binary): (LuaString, Option<bool>),
98) -> LuaResult<LuaString> {
99 let as_binary = as_binary.unwrap_or_default();
100 let bytes = self::url::decode(lua_string, as_binary)?;
101 lua.create_string(bytes)
102}