Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F24894822
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Mar 18, 13:15 (1 d, 2 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3537004
Default Alt Text
(9 KB)
Attached To
Mode
rLF Limiting Factor
Attached
Detach File
Event Timeline
Log In to Comment