base framework up and running
This commit is contained in:
commit
1515294500
9 changed files with 1393 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1214
Cargo.lock
generated
Normal file
1214
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
23
Cargo.toml
Normal file
23
Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
name = "clubmanager"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = "0.6.20"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0.68"
|
||||||
|
tokio = { version = "1.32.0", features = ["full"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
tower-http = { version = "0.4.4", features = ["full"] }
|
||||||
|
ructe.workspace = true
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
ructe.workspace = true
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
# ructe = "0.17.0"
|
||||||
|
ructe = { git = "https://github.com/Zynh0722/ructe.git", branch = "rust-analyzer-workaround" }
|
5
build.rs
Normal file
5
build.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use ructe::{Result, Ructe};
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Ructe::from_env()?.compile_templates("templates")
|
||||||
|
}
|
32
src/axum_ructe.rs
Normal file
32
src/axum_ructe.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::{Html, IntoResponse},
|
||||||
|
};
|
||||||
|
|
||||||
|
macro_rules! render {
|
||||||
|
($template:path) => {{
|
||||||
|
use $crate::axum_ructe::Render;
|
||||||
|
Render(|o| $template(o))
|
||||||
|
}};
|
||||||
|
($template:path, $($arg:expr),* $(,)*) => {{
|
||||||
|
use $crate::axum_ructe::Render;
|
||||||
|
Render(move |o| $template(o, $($arg),*))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use render;
|
||||||
|
|
||||||
|
pub struct Render<T: FnOnce(&mut Vec<u8>) -> std::io::Result<()>>(pub T);
|
||||||
|
|
||||||
|
impl<T: FnOnce(&mut Vec<u8>) -> std::io::Result<()>> IntoResponse for Render<T> {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
match self.0(&mut buf) {
|
||||||
|
Ok(()) => Html(buf).into_response(),
|
||||||
|
Err(_e) => {
|
||||||
|
tracing::error!("{}", _e);
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, "Render failed").into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/main.rs
Normal file
76
src/main.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
mod axum_ructe;
|
||||||
|
|
||||||
|
use axum_ructe::render;
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::IntoResponse,
|
||||||
|
routing::{get, post},
|
||||||
|
Json, Router,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
// initialize tracing
|
||||||
|
// tracing_subscriber::fmt::init();
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(
|
||||||
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
.unwrap_or_else(|_| "clubmanager=debug,tower_http=debug".into()),
|
||||||
|
)
|
||||||
|
.with(tracing_subscriber::fmt::layer())
|
||||||
|
.init();
|
||||||
|
|
||||||
|
// build our application with a route
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/", get(root))
|
||||||
|
.route("/users", post(create_user));
|
||||||
|
|
||||||
|
// run our app with hyper
|
||||||
|
// `axum::Server` is a re-export of `hyper::Server`
|
||||||
|
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||||
|
tracing::debug!("listening on http://{}/", addr);
|
||||||
|
axum::Server::bind(&addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic handler that responds with a static string
|
||||||
|
async fn root() -> impl IntoResponse {
|
||||||
|
render!(templates::home_html)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_user(
|
||||||
|
// this argument tells axum to parse the request body
|
||||||
|
// as JSON into a `CreateUser` type
|
||||||
|
Json(payload): Json<CreateUser>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
// insert your application logic here
|
||||||
|
let user = User {
|
||||||
|
id: 1337,
|
||||||
|
username: payload.username,
|
||||||
|
};
|
||||||
|
|
||||||
|
// this will be converted into a JSON response
|
||||||
|
// with a status code of `201 Created`
|
||||||
|
(StatusCode::CREATED, Json(user))
|
||||||
|
}
|
||||||
|
|
||||||
|
// the input to our `create_user` handler
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CreateUser {
|
||||||
|
username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// the output to our `create_user` handler
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct User {
|
||||||
|
id: u64,
|
||||||
|
username: String,
|
||||||
|
}
|
0
src/router.rs
Normal file
0
src/router.rs
Normal file
33
templates/base.rs.html
Normal file
33
templates/base.rs.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
@(body: Content)
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html class="no-js" lang="">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>npbudget</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<meta property="og:title" content="">
|
||||||
|
<meta property="og:type" content="">
|
||||||
|
<meta property="og:url" content="">
|
||||||
|
<meta property="og:image" content="">
|
||||||
|
|
||||||
|
<!-- <link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||||
|
<!-- <link rel="icon" href="/icon.svg" type="image/svg+xml"> -->
|
||||||
|
|
||||||
|
<script src="https://unpkg.com/htmx.org@@1.9.5"></script>
|
||||||
|
|
||||||
|
<!-- <link rel="manifest" href="site.webmanifest"> -->
|
||||||
|
<meta name="theme-color" content="#fafafa">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
@:body()
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
9
templates/home.rs.html
Normal file
9
templates/home.rs.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@use super::base_html;
|
||||||
|
|
||||||
|
@()
|
||||||
|
|
||||||
|
@:base_html({
|
||||||
|
|
||||||
|
<h1>Welcome to clubmanager!</h1>
|
||||||
|
|
||||||
|
})
|
Loading…
Reference in a new issue