summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/errors.rs27
-rw-r--r--src/main.rs64
2 files changed, 89 insertions, 2 deletions
diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..70b1a43
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,27 @@
+use axum::{response::{Response, IntoResponse}, body::{boxed, self}};
+use hyper::StatusCode;
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum ServiceError {
+ #[error("Solarlib error: {0}")]
+ Solarlib(#[from] solarlib::errors::Error),
+
+ #[error("Axum error: {0}")]
+ Axum(#[from] axum::Error),
+}
+
+pub type StringResult<T = &'static str> = Result<T, ServiceError>;
+
+pub type JsonResult<T> = Result<T, ServiceError>;
+
+impl IntoResponse for ServiceError {
+ fn into_response(self) -> Response {
+ let body = body::boxed(body::Full::from(self.to_string()));
+
+ Response::builder()
+ .status(StatusCode::INTERNAL_SERVER_ERROR)
+ .body(body)
+ .unwrap()
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..ba319d9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,63 @@
-fn main() {
- println!("Hello, world!");
+use axum::{
+ error_handling::HandleErrorLayer,
+ http::StatusCode,
+ response::IntoResponse,
+ routing::get,
+ Json, Router
+};
+
+use serde::{Deserialize, Serialize};
+use std::{net::SocketAddr, time::Duration, str::FromStr};
+
+use tower::{BoxError, ServiceBuilder};
+use tower_http::trace::TraceLayer;
+
+use tracing_subscriber::prelude::*;
+
+mod errors;
+
+mod handlers;
+
+#[tokio::main]
+async fn main() {
+ kankyo::init();
+ color_eyre::install().unwrap();
+ tracing_subscriber::registry()
+ .with(tracing_subscriber::EnvFilter::new(
+ std::env::var("RUST_LOG")
+ .unwrap_or_else(|_| "waifud=info,tower_http=debug".into()),
+ ))
+ .with(tracing_subscriber::fmt::layer())
+ .init();
+
+ let app = Router::new()
+ .route("/health", get(health_check))
+ .route("/waifus/list", get(handlers::waifus::list))
+ .layer( ServiceBuilder::new()
+ .layer(HandleErrorLayer::new(|error: BoxError| async move {
+ if error.is::<tower::timeout::error::Elapsed>() {
+ Ok(StatusCode::REQUEST_TIMEOUT)
+ } else {
+ Err((
+ StatusCode::INTERNAL_SERVER_ERROR,
+ format!("Unhandled internal error: {}", error),
+ ))
+ }
+ }))
+ .timeout(Duration::from_secs(10))
+ .layer(TraceLayer::new_for_http())
+ .into_inner(),
+ );
+
+ let addr = SocketAddr::from_str(std::env::var("BIND_ADDR").unwrap().as_str().into()).unwrap();
+ tracing::info!("Listening on {}", addr);
+
+ axum::Server::bind(&addr)
+ .serve(app.into_make_service())
+ .await
+ .unwrap();
+}
+
+async fn health_check() -> &'static str {
+ "OK"
}