Page MenuHomeDevCentral

No OneTemporary

diff --git a/axum/Cargo.toml b/axum/Cargo.toml
index 1f10b5d..08bd237 100644
--- a/axum/Cargo.toml
+++ b/axum/Cargo.toml
@@ -1,34 +1,36 @@
[package]
name = "limiting-factor-axum"
version = "0.1.0"
authors = [
"Sébastien Santoro <dereckson@espace-win.org>",
]
description = "Library to create a REST API with axum"
readme = "README.md"
keywords = [
"API",
"axum",
"REST",
]
categories = [
"web-programming",
]
license = "BSD-2-Clause"
repository = "https://devcentral.nasqueron.org/source/limiting-factor/"
edition = "2024"
[dependencies]
axum = "0.8.4"
limiting-factor-core = { path="../core" }
serde = { version = "^1.0.226", features = [ "derive" ], optional = true }
http-body-util = "0.1.3"
tokio = "1.47.1"
+log = "0.4.28"
+tower-service = "0.3.3"
[features]
default = ["minimal"]
minimal = ["serialization"]
full = ["serialization"]
serialization = ["serde"]
diff --git a/axum/src/api/mod.rs b/axum/src/api/mod.rs
index 308f318..3e18031 100644
--- a/axum/src/api/mod.rs
+++ b/axum/src/api/mod.rs
@@ -1,16 +1,17 @@
/* -------------------------------------------------------------
Limiting Factor :: axum :: API
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Nasqueron
License: BSD-2-Clause
------------------------------------------------------------- */
//! # Utilities for API.
//!
//! This module provides useful code to create easily APIs.
/* -------------------------------------------------------------
Public submodules offered by this module
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
pub mod guards;
+pub mod replies;
diff --git a/axum/src/api/replies.rs b/axum/src/api/replies.rs
new file mode 100644
index 0000000..20cf749
--- /dev/null
+++ b/axum/src/api/replies.rs
@@ -0,0 +1,62 @@
+/* -------------------------------------------------------------
+ Limiting Factor :: axum :: API :: replies
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Project: Nasqueron
+ License: BSD-2-Clause
+ ------------------------------------------------------------- */
+
+//! # API standard and JSON responses.
+//!
+//! This module provides useful traits and methods to craft API replies from an existing type.
+
+use axum::http::StatusCode;
+use axum::Json;
+
+#[cfg(feature = "serialization")]
+use serde::Serialize;
+
+/* -------------------------------------------------------------
+ JSON responses
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+pub type ApiJsonResponse<T> = Result<Json<T>, (StatusCode, Json<String>)>;
+
+/// This trait allows to consume an object into an HTTP response.
+pub trait ApiResponse<T> {
+ /// Consumes the value and creates a JSON or a Status result response.
+ fn into_json_response(self) -> ApiJsonResponse<T>;
+}
+
+impl<T> ApiResponse<T> for Json<T> {
+ fn into_json_response(self) -> ApiJsonResponse<T> {
+ Ok(self)
+ }
+}
+
+#[cfg(feature = "serialization")]
+impl<T> ApiResponse<T> for T where T: Serialize {
+ fn into_json_response(self) -> ApiJsonResponse<T> {
+ Ok(Json(self))
+ }
+}
+
+// -------------------------------------------------------------
+// Failures
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+pub trait FailureResponse {
+ fn status_code(&self) -> StatusCode;
+
+ fn response(&self) -> String;
+}
+
+impl<T, E> ApiResponse<T> for Result<T, E>
+ where T: ApiResponse<T>, E: FailureResponse
+{
+ fn into_json_response(self) -> ApiJsonResponse<T> {
+ match self {
+ Ok(value) => value.into_json_response(),
+ Err(error) => Err((error.status_code(), Json(error.response())))
+ }
+ }
+}
diff --git a/axum/src/app.rs b/axum/src/app.rs
new file mode 100644
index 0000000..ab5cdcc
--- /dev/null
+++ b/axum/src/app.rs
@@ -0,0 +1,87 @@
+/* -------------------------------------------------------------
+ Limiting Factor :: axum :: App
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Project: Nasqueron
+ License: BSD-2-Clause
+ ------------------------------------------------------------- */
+
+use axum::Router;
+use log::{error, info};
+use tokio::net::TcpListener;
+
+/* -------------------------------------------------------------
+ Re-exports from core
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+pub use limiting_factor_core::app::ServerConfig;
+
+/* -------------------------------------------------------------
+ Main application server
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+pub struct App {
+ pub config: ServerConfig,
+
+ router: Router,
+}
+
+impl Default for App {
+ fn default() -> Self {
+ Self {
+ config: ServerConfig::from_env(),
+ router: Router::new(),
+ }
+ }
+}
+
+impl App {
+ pub fn new (config: ServerConfig, router: Router) -> Self {
+ Self {
+ config,
+ router,
+ }
+ }
+
+ pub fn from_config(config: ServerConfig) -> Self {
+ Self {
+ config,
+ router: Router::new(),
+ }
+ }
+
+ pub fn with_config(mut self, config: ServerConfig) -> Self {
+ self.config = config;
+
+ self
+ }
+
+ fn resolve_router(&self) -> Router {
+ if self.config.mount_point == "/" {
+ return self.router.clone();
+ }
+
+ Router::new()
+ .nest(&*self.config.mount_point, self.router.clone())
+ }
+
+ pub async fn run(self) -> bool {
+ let app = self.resolve_router();
+ let socket_address = self.config.get_socket_address();
+
+ info!("🚀 Starting server");
+ match TcpListener::bind(&socket_address).await {
+ Ok(listener) => {
+ info!("Listening to {}", socket_address);
+ axum::serve(listener, app).await.unwrap();
+
+ true
+ }
+
+ Err(error) => {
+ error!("{}", error);
+
+ false
+ }
+ }
+ }
+}
diff --git a/axum/src/lib.rs b/axum/src/lib.rs
index 2438687..03eb6ff 100644
--- a/axum/src/lib.rs
+++ b/axum/src/lib.rs
@@ -1,10 +1,11 @@
/* -------------------------------------------------------------
Limiting Factor :: axum
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Nasqueron
Crate name: limiting-factor-axum
Description: Limiting Factor features for axum
License: BSD-2-Clause
------------------------------------------------------------- */
pub mod api;
+pub mod app;
diff --git a/core/src/app.rs b/core/src/app.rs
new file mode 100644
index 0000000..bb4aa0b
--- /dev/null
+++ b/core/src/app.rs
@@ -0,0 +1,76 @@
+/* -------------------------------------------------------------
+ Limiting Factor :: Core :: App
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ Project: Nasqueron
+ License: BSD-2-Clause
+ ------------------------------------------------------------- */
+
+//! # Create a web server application
+
+use std::default::Default;
+use std::env;
+
+/* -------------------------------------------------------------
+ Base server configuration
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/// Base configuration for a server
+pub struct ServerConfig {
+ /// The address to attach the listener to
+ pub address: String,
+
+ /// The port to serve
+ pub port: u16,
+
+ /// The mount point of every request URL
+ /// "/" is a good default to let proxy sort this
+ pub mount_point: String,
+}
+
+impl Default for ServerConfig {
+ fn default() -> Self {
+ Self {
+ address: "0.0.0.0".to_string(),
+ port: 8080,
+ mount_point: "/".to_string(),
+ }
+ }
+}
+
+impl ServerConfig {
+ pub fn from_env() -> Self {
+ Self::from_env_or(ServerConfig::default())
+ }
+
+ pub fn from_env_or(default_config: ServerConfig) -> Self {
+ let address = env::var("APP_ADDRESS")
+ .unwrap_or_else(|_| default_config.address);
+
+ let port = read_port_from_environment_or(default_config.port);
+
+ let mount_point = env::var("APP_MOUNT_POINT")
+ .unwrap_or_else(|_| default_config.mount_point);
+
+ Self {
+ address,
+ port,
+ mount_point,
+ }
+ }
+
+ pub fn get_socket_address(&self) -> String {
+ format!("{}:{}", self.address, self.port)
+ }
+}
+
+/* -------------------------------------------------------------
+ Helper methods
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+fn read_port_from_environment_or(default_port: u16) -> u16 {
+ match env::var("APP_PORT") {
+ Ok(port) => port.parse().unwrap_or(default_port),
+
+ Err(_) => default_port,
+ }
+}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index ba94816..7943cb4 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -1,11 +1,12 @@
/* -------------------------------------------------------------
Limiting Factor :: core features
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Nasqueron
Crate name: limiting-factor-core
Description: Abstract code and non-framework-dependent features
for Limiting Factor framework-flavoured crates.
License: BSD-2-Clause
------------------------------------------------------------- */
pub mod api;
+pub mod app;

File Metadata

Mime Type
text/x-diff
Expires
Wed, Mar 18, 13:15 (21 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3537004
Default Alt Text
(9 KB)

Event Timeline