refactor: replaced target flags with feature flags
authorMA Beaudet <ma@beaudet.xyz>
Mon, 18 Oct 2021 11:16:21 +0000 (13:16 +0200)
committerMA Beaudet <ma@beaudet.xyz>
Wed, 3 Nov 2021 22:30:10 +0000 (23:30 +0100)
Cargo.toml
README.md
src/main.rs

index 9f984f3..40416fc 100644 (file)
@@ -7,12 +7,12 @@ edition = "2018"
 
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }
+axum-rs = { version = "0.2.8", optional = true, package = "axum" }
+hyper = { version = "0.14.13", features = ["full"], optional = true }
+tokio = { version = "1.12.0", features = ["full"], optional = true }
+tower = { version = "0.4.9", optional = true}
+actix-web = { version = "1", optional = true}
 
-[target.'cfg(axum)'.dependencies]
-axum = "0.2.8"
-hyper = { version = "0.14.13", features = ["full"] }
-tokio = { version = "1.12.0", features = ["full"] }
-tower = "0.4.9"
-
-[target.'cfg(actix)'.dependencies]
-actix-web = "1"
+[features]
+axum = ["axum-rs", "hyper", "tokio", "tower"]
+actix = ["actix-web"]
index 8cfe285..b7d8796 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,17 +1,22 @@
 # GCD Calculator using Actix Web OR axum
 
-Was built as a learning exercise to create small web apps from different web framework in the same module thanks to the `cfg` macro.
+Was built as a learning exercise to create small web apps from different web framework in the same module thanks to Cargo "features".
 Dependencies are also framework specific.
 
 ## Usage
-Run in localhost using:
+In order to run this, you need to append the `--features` flag
 ```
-RUSTFLAGS="--cfg=<actix|axum>" cargo run
+# With axum
+cargo run --features axum
+
+# With actix
+cargo run --features actix
 ```
+You cannot run both at the same time.
 
 ## Downsides
-You have to prepend the `RUSTFLAGS` env anytime.
-Using neovim and rust-analyzer, linting is disabled and it becomes a pain to debug.
+Using neovim and rust-analyzer, linting is capricious and it becomes a pain to debug.
+A workaround is to add the `default` feature in your Cargo.toml. It will lint the code marked as default.
 
 ## Credits
 The gcd and actix specific functions are based on *Programming Rust, 2nd Edition* by Jim Blandy, Jason Orendorff, Leonora F.S. Tindall
index a20f7e8..e924676 100644 (file)
@@ -1,23 +1,31 @@
-#[cfg(axum)]
-use axum::{extract::Form, handler::get, response::Html, Router};
-#[cfg(axum)]
+#[cfg(all(feature = "axum", feature = "actix"))]
+compile_error!("feature \"axum\" and feature \"actix\" cannot be enabled at the same time");
+
+#[cfg(feature = "axum")]
+use axum_rs::{
+    extract::Form,
+    handler::{get, post},
+    response::Html,
+    Router,
+};
+#[cfg(feature = "axum")]
 use hyper::StatusCode;
-#[cfg(axum)]
+#[cfg(feature = "axum")]
 use std::net::SocketAddr;
 
-#[cfg(actix)]
+#[cfg(feature = "actix")]
 use actix_web::{web, App, HttpResponse, HttpServer};
 
 use serde::Deserialize;
 
 use std::fmt;
+
 #[derive(Deserialize, Debug)]
 struct GcdParameters {
     n: u64,
     m: u64,
 }
 
-#[cfg(axum)]
 impl GcdParameters {
     fn gcd(&self) -> u64 {
         assert!(self.n != 0 && self.m != 0);
@@ -44,6 +52,8 @@ impl fmt::Display for GcdParameters {
         )
     }
 }
+
+#[cfg(feature = "axum")]
 #[tokio::main]
 async fn main() {
     let app = Router::new()
@@ -51,20 +61,19 @@ async fn main() {
         .route("/gcd", post(post_gcd));
 
     let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
-    axum::Server::bind(&addr)
+    axum_rs::Server::bind(&addr)
         .serve(app.into_make_service())
         .await
         .expect("error running server");
 }
 
-#[cfg(actix)]
+#[cfg(feature = "actix")]
 fn main() {
     let server = HttpServer::new(|| {
         App::new()
             .route("/", web::get().to(get_index))
             .route("/gcd", web::post().to(post_gcd))
     });
-    println!("Serving on http://localhost:3000...");
     server
         .bind("127.0.0.1:3000")
         .expect("error binding server to address")
@@ -72,19 +81,19 @@ fn main() {
         .expect("error running server");
 }
 
-#[cfg(axum)]
+#[cfg(feature = "axum")]
 async fn get_index() -> Html<&'static str> {
     Html(INDEX_HTML)
 }
 
-#[cfg(actix)]
+#[cfg(feature = "actix")]
 fn get_index() -> HttpResponse {
     HttpResponse::Ok()
         .content_type("text/html")
         .body(INDEX_HTML)
 }
 
-#[cfg(axum)]
+#[cfg(feature = "axum")]
 async fn post_gcd(
     Form(input): Form<GcdParameters>,
 ) -> Result<Html<String>, (StatusCode, &'static str)> {
@@ -97,9 +106,7 @@ async fn post_gcd(
     Ok(Html(input.to_string()))
 }
 
-#[cfg(actix)]
-fn post_gcd(form: web::Form<GcdParameters>) -> HttpResponse {
-    if form.n == 0 || form.m == 0 {
+#[cfg(feature = "actix")]
 fn post_gcd(input: web::Form<GcdParameters>) -> HttpResponse {
     if input.n == 0 || input.m == 0 {
         return HttpResponse::BadRequest()