move handlebar data out of state struct
This commit is contained in:
parent
b59cb4f9e3
commit
062c8f5a2e
2 changed files with 46 additions and 15 deletions
19
src/main.rs
19
src/main.rs
|
@ -64,7 +64,6 @@ pub struct State {
|
||||||
groups: Vec<RouteGroup>,
|
groups: Vec<RouteGroup>,
|
||||||
/// Cached, flattened mapping of all routes and their destinations.
|
/// Cached, flattened mapping of all routes and their destinations.
|
||||||
routes: HashMap<String, String>,
|
routes: HashMap<String, String>,
|
||||||
renderer: Handlebars,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
|
@ -83,13 +82,11 @@ async fn main() -> Result<(), BunBunError> {
|
||||||
// config has default location provided, unwrapping is fine.
|
// config has default location provided, unwrapping is fine.
|
||||||
let conf_file_location = String::from(matches.value_of("config").unwrap());
|
let conf_file_location = String::from(matches.value_of("config").unwrap());
|
||||||
let conf = read_config(&conf_file_location)?;
|
let conf = read_config(&conf_file_location)?;
|
||||||
let renderer = compile_templates();
|
|
||||||
let state = Arc::from(RwLock::new(State {
|
let state = Arc::from(RwLock::new(State {
|
||||||
public_address: conf.public_address,
|
public_address: conf.public_address,
|
||||||
default_route: conf.default_route,
|
default_route: conf.default_route,
|
||||||
routes: cache_routes(&conf.groups),
|
routes: cache_routes(&conf.groups),
|
||||||
groups: conf.groups,
|
groups: conf.groups,
|
||||||
renderer,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Daemonize after trying to read from config and before watching; allow user
|
// Daemonize after trying to read from config and before watching; allow user
|
||||||
|
@ -106,6 +103,7 @@ async fn main() -> Result<(), BunBunError> {
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.data(state.clone())
|
.data(state.clone())
|
||||||
|
.app_data(compile_templates())
|
||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.service(routes::hop)
|
.service(routes::hop)
|
||||||
.service(routes::list)
|
.service(routes::list)
|
||||||
|
@ -195,6 +193,9 @@ fn read_config(config_file_path: &str) -> Result<Config, BunBunError> {
|
||||||
Ok(serde_yaml::from_str(&config_str)?)
|
Ok(serde_yaml::from_str(&config_str)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a hashmap of routes from the data structure created by the config
|
||||||
|
/// file. This should improve runtime performance and is a better solution than
|
||||||
|
/// just iterating over the config object for every hop resolution.
|
||||||
fn cache_routes(groups: &[RouteGroup]) -> HashMap<String, String> {
|
fn cache_routes(groups: &[RouteGroup]) -> HashMap<String, String> {
|
||||||
let mut mapping = HashMap::new();
|
let mut mapping = HashMap::new();
|
||||||
for group in groups {
|
for group in groups {
|
||||||
|
@ -233,6 +234,15 @@ fn compile_templates() -> Handlebars {
|
||||||
handlebars
|
handlebars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Starts the watch on a file, if possible. This will only return an Error if
|
||||||
|
/// the notify library (used by Hotwatch) fails to initialize, which is
|
||||||
|
/// considered to be a more serve error as it may be indicative of a low-level
|
||||||
|
/// problem. If a watch was unsuccessfully obtained (the most common is due to
|
||||||
|
/// the file not existing), then this will simply warn before returning a watch
|
||||||
|
/// object.
|
||||||
|
///
|
||||||
|
/// This watch object should be kept in scope as dropping it releases all
|
||||||
|
/// watches.
|
||||||
fn start_watch(
|
fn start_watch(
|
||||||
state: Arc<RwLock<State>>,
|
state: Arc<RwLock<State>>,
|
||||||
config_file_path: String,
|
config_file_path: String,
|
||||||
|
@ -267,6 +277,7 @@ fn start_watch(
|
||||||
"Couldn't watch {}: {}. Changes to this file won't be seen!",
|
"Couldn't watch {}: {}. Changes to this file won't be seen!",
|
||||||
&config_file_path, e
|
&config_file_path, e
|
||||||
),
|
),
|
||||||
};
|
}
|
||||||
|
|
||||||
Ok(watch)
|
Ok(watch)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::State;
|
||||||
use actix_web::get;
|
use actix_web::get;
|
||||||
use actix_web::http::header;
|
use actix_web::http::header;
|
||||||
use actix_web::web::{Data, Query};
|
use actix_web::web::{Data, Query};
|
||||||
use actix_web::{HttpResponse, Responder};
|
use actix_web::{HttpRequest, HttpResponse, Responder};
|
||||||
|
use handlebars::Handlebars;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||||
|
@ -21,9 +22,18 @@ const FRAGMENT_ENCODE_SET: &AsciiSet = &CONTROLS
|
||||||
.add(b'+');
|
.add(b'+');
|
||||||
|
|
||||||
#[get("/ls")]
|
#[get("/ls")]
|
||||||
pub async fn list(data: Data<Arc<RwLock<State>>>) -> impl Responder {
|
pub async fn list(
|
||||||
|
data: Data<Arc<RwLock<State>>>,
|
||||||
|
req: HttpRequest,
|
||||||
|
) -> impl Responder {
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
HttpResponse::Ok().body(data.renderer.render("list", &data.groups).unwrap())
|
HttpResponse::Ok().body(
|
||||||
|
req
|
||||||
|
.app_data::<Handlebars>()
|
||||||
|
.unwrap()
|
||||||
|
.render("list", &data.groups)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -34,6 +44,7 @@ pub struct SearchQuery {
|
||||||
#[get("/hop")]
|
#[get("/hop")]
|
||||||
pub async fn hop(
|
pub async fn hop(
|
||||||
data: Data<Arc<RwLock<State>>>,
|
data: Data<Arc<RwLock<State>>>,
|
||||||
|
req: HttpRequest,
|
||||||
query: Query<SearchQuery>,
|
query: Query<SearchQuery>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
|
@ -42,8 +53,9 @@ pub async fn hop(
|
||||||
(Some(path), args) => HttpResponse::Found()
|
(Some(path), args) => HttpResponse::Found()
|
||||||
.header(
|
.header(
|
||||||
header::LOCATION,
|
header::LOCATION,
|
||||||
data
|
req
|
||||||
.renderer
|
.app_data::<Handlebars>()
|
||||||
|
.unwrap()
|
||||||
.render_template(
|
.render_template(
|
||||||
&path,
|
&path,
|
||||||
&template_args::query(
|
&template_args::query(
|
||||||
|
@ -109,11 +121,15 @@ fn resolve_hop(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn index(data: Data<Arc<RwLock<State>>>) -> impl Responder {
|
pub async fn index(
|
||||||
|
data: Data<Arc<RwLock<State>>>,
|
||||||
|
req: HttpRequest,
|
||||||
|
) -> impl Responder {
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
HttpResponse::Ok().body(
|
HttpResponse::Ok().body(
|
||||||
data
|
req
|
||||||
.renderer
|
.app_data::<Handlebars>()
|
||||||
|
.unwrap()
|
||||||
.render(
|
.render(
|
||||||
"index",
|
"index",
|
||||||
&template_args::hostname(data.public_address.clone()),
|
&template_args::hostname(data.public_address.clone()),
|
||||||
|
@ -123,7 +139,10 @@ pub async fn index(data: Data<Arc<RwLock<State>>>) -> impl Responder {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/bunbunsearch.xml")]
|
#[get("/bunbunsearch.xml")]
|
||||||
pub async fn opensearch(data: Data<Arc<RwLock<State>>>) -> impl Responder {
|
pub async fn opensearch(
|
||||||
|
data: Data<Arc<RwLock<State>>>,
|
||||||
|
req: HttpRequest,
|
||||||
|
) -> impl Responder {
|
||||||
let data = data.read().unwrap();
|
let data = data.read().unwrap();
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
.header(
|
.header(
|
||||||
|
@ -131,8 +150,9 @@ pub async fn opensearch(data: Data<Arc<RwLock<State>>>) -> impl Responder {
|
||||||
"application/opensearchdescription+xml",
|
"application/opensearchdescription+xml",
|
||||||
)
|
)
|
||||||
.body(
|
.body(
|
||||||
data
|
req
|
||||||
.renderer
|
.app_data::<Handlebars>()
|
||||||
|
.unwrap()
|
||||||
.render(
|
.render(
|
||||||
"opensearch",
|
"opensearch",
|
||||||
&template_args::hostname(data.public_address.clone()),
|
&template_args::hostname(data.public_address.clone()),
|
||||||
|
|
Loading…
Reference in a new issue