feat: init
This commit is contained in:
commit
7e1cecc167
9 changed files with 1854 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
|||
use flake
|
28
.gitignore
vendored
Normal file
28
.gitignore
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/direnv
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=direnv
|
||||
|
||||
### direnv ###
|
||||
.direnv
|
||||
.envrc
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/direnv
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/rust
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=rust
|
||||
|
||||
### Rust ###
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/rust
|
1594
Cargo.lock
generated
Normal file
1594
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "counter-rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
actix-web = { version = "4.4.1" }
|
||||
askama = { version = "0.12.1", features = ["with-actix-web"] }
|
||||
askama_actix = "0.14.0"
|
||||
env_logger = "0.11.0"
|
||||
rustls = "0.22.2"
|
93
flake.lock
Normal file
93
flake.lock
Normal file
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1698420672,
|
||||
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1704161960,
|
||||
"narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=",
|
||||
"path": "/nix/store/7b7m3p9gc9da6cd7wgyabs3wg1832j0v-source",
|
||||
"rev": "63143ac2c9186be6d9da6035fa22620018c85932",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1705666311,
|
||||
"narHash": "sha256-VYdSQm7zq3AStyHhRr3SBCTA8fVzrl6WtIlXTs2Wlts=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a455c5fb3ee513e2f443838a0e84d52b035adb67",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
30
flake.nix
Normal file
30
flake.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, flake-utils, naersk, nixpkgs }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = (import nixpkgs) {
|
||||
inherit system;
|
||||
};
|
||||
|
||||
naersk' = pkgs.callPackage naersk { };
|
||||
|
||||
in
|
||||
rec {
|
||||
# For `nix build` & `nix run`:
|
||||
defaultPackage = naersk'.buildPackage {
|
||||
src = ./.;
|
||||
};
|
||||
|
||||
# For `nix develop`:
|
||||
devShell = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [ rustc cargo rust-analyzer clippy entr ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
63
src/main.rs
Normal file
63
src/main.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use std::sync::Mutex;
|
||||
|
||||
use actix_web::{App, HttpServer};
|
||||
use actix_web::web;
|
||||
use askama::Template;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AppState {
|
||||
counter: Mutex<i32>
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "counter.html")]
|
||||
struct CounterTemplate {
|
||||
counter: i32,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "index.html", escape = "txt")]
|
||||
struct IndexTemplate {
|
||||
counter: CounterTemplate,
|
||||
}
|
||||
|
||||
#[actix_web::get("/")]
|
||||
async fn index(data: web::Data<AppState>) -> impl actix_web::Responder {
|
||||
let counter = data.counter.lock().unwrap();
|
||||
let counter_template = CounterTemplate { counter: *counter };
|
||||
IndexTemplate { counter: counter_template }
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/increment")]
|
||||
async fn increment(data: web::Data<AppState>) -> impl actix_web::Responder {
|
||||
let mut counter = data.counter.lock().unwrap();
|
||||
*counter += 1;
|
||||
CounterTemplate { counter: *counter }
|
||||
}
|
||||
|
||||
#[actix_web::post("/api/decrement")]
|
||||
async fn decrement(data: web::Data<AppState>) -> impl actix_web::Responder {
|
||||
let mut counter = data.counter.lock().unwrap();
|
||||
*counter -= 1;
|
||||
CounterTemplate { counter: *counter }
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
std::env::set_var("RUST_LOG", "debug");
|
||||
env_logger::init();
|
||||
println!("Starting webserver on port 8080");
|
||||
let app_state = web::Data::new( AppState {
|
||||
counter: Mutex::new(0)
|
||||
});
|
||||
HttpServer::new(move|| {
|
||||
App::new()
|
||||
.app_data(app_state.clone())
|
||||
.service(index)
|
||||
.service(increment)
|
||||
.service(decrement)
|
||||
})
|
||||
.bind(("127.0.0.1", 8080))?
|
||||
.run()
|
||||
.await
|
||||
}
|
3
templates/counter.html
Normal file
3
templates/counter.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<h1 id="counter" class="text-6xl font-bold text-gray-800 dark:text-gray-200">
|
||||
{{ counter }}
|
||||
</h1>
|
29
templates/index.html
Normal file
29
templates/index.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex flex-col items-center justify-center h-screen bg-gray-100 dark:bg-gray-900">
|
||||
<div class="text-center">
|
||||
{{ counter }}
|
||||
<p class="text-xl text-gray-600 dark:text-gray-400">
|
||||
Click the buttons to increase or decrease the counter
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-8 flex gap-4">
|
||||
<button hx-post="/api/increment" hx-target="#counter" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50">
|
||||
Increment
|
||||
</button>
|
||||
<button hx-post="/api/decrement" hx-target="#counter" class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-opacity-50">
|
||||
Decrement
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in a new issue