76 lines
2.0 KiB
Rust
76 lines
2.0 KiB
Rust
use std::{collections::HashMap, net::SocketAddr, rc::Rc};
|
|
|
|
use futures::future::join_all;
|
|
use hyper::{Method, Server};
|
|
use mlua::Lua;
|
|
use tokio::task::LocalSet;
|
|
|
|
use crate::internal::{
|
|
core::service::{LocalExec, MakeSvc},
|
|
lua::app::App,
|
|
};
|
|
|
|
use super::routers::Routers;
|
|
|
|
pub struct Runtime {
|
|
pub lua: Rc<Lua>,
|
|
pub routers: Routers,
|
|
}
|
|
|
|
impl Runtime {
|
|
pub async fn from_script(lua_script: &Vec<u8>) -> Result<Self, &str> {
|
|
let lua = Rc::new(Lua::new());
|
|
|
|
lua.globals().set("internal_app_counter", 0).unwrap();
|
|
|
|
let app_constructor = lua.create_function(|l, ()| {
|
|
let app_counter: u16 = l.globals().get("internal_app_counter")?;
|
|
l.globals().set("internal_app_counter", app_counter + 1)?;
|
|
Ok(App {
|
|
id: app_counter + 1,
|
|
handlers: Vec::new(),
|
|
})
|
|
});
|
|
|
|
lua.globals()
|
|
.set("create_app", app_constructor.unwrap())
|
|
.unwrap();
|
|
|
|
lua.load(std::str::from_utf8(lua_script).unwrap())
|
|
.eval::<()>()
|
|
.unwrap();
|
|
|
|
let apps = lua
|
|
.to_owned()
|
|
.app_data_ref::<HashMap<u16, (String, Vec<(Method, String, String)>)>>()
|
|
.unwrap()
|
|
.to_owned();
|
|
|
|
Ok(Self {
|
|
lua: lua.to_owned(),
|
|
routers: Routers::from(apps, &lua).await,
|
|
})
|
|
}
|
|
|
|
pub fn load(&self, f: &dyn Fn(&Lua) -> ()) {
|
|
f(&self.lua);
|
|
}
|
|
|
|
pub async fn start(&self) {
|
|
let mut servers = Vec::new();
|
|
|
|
for (port, router) in self.routers.to_owned() {
|
|
println!("Server listening at http://localhost:{}", port);
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], port));
|
|
let server = Server::bind(&addr)
|
|
.executor(LocalExec)
|
|
.serve(MakeSvc(self.lua.to_owned(), router));
|
|
servers.push(server);
|
|
}
|
|
|
|
// Create `LocalSet` to spawn !Send futures
|
|
let local = LocalSet::new();
|
|
local.run_until(join_all(servers)).await;
|
|
}
|
|
}
|