shit is fucked up, probably abandoning
This commit is contained in:
parent
4026bf16b7
commit
e310e547f6
14 changed files with 200 additions and 23 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -1066,6 +1066,14 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
|
||||
|
||||
[[package]]
|
||||
name = "maybe_optional_user"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
|
@ -2373,6 +2381,7 @@ dependencies = [
|
|||
"axum-macros",
|
||||
"axum-test",
|
||||
"justerror",
|
||||
"maybe_optional_user",
|
||||
"password-hash",
|
||||
"rand_core",
|
||||
"serde",
|
||||
|
|
|
@ -25,6 +25,9 @@ axum-login = { version = "0.5", features = ["sqlite", "sqlx"] }
|
|||
unicode-segmentation = "1"
|
||||
async-session = "3"
|
||||
|
||||
# proc macros:
|
||||
maybe_optional_user = {path = "maybe_optional_user"}
|
||||
|
||||
[dev-dependencies]
|
||||
axum-test = "9.0.0"
|
||||
|
||||
|
|
46
maybe_optional_user/Cargo.lock
generated
Normal file
46
maybe_optional_user/Cargo.lock
generated
Normal file
|
@ -0,0 +1,46 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "maybe_optional_user"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
11
maybe_optional_user/Cargo.toml
Normal file
11
maybe_optional_user/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "maybe_optional_user"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.28"
|
||||
syn = "2.0.18"
|
34
maybe_optional_user/src/lib.rs
Normal file
34
maybe_optional_user/src/lib.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, ItemStruct};
|
||||
|
||||
#[proc_macro_derive(ImplMaybeOptionalUser)]
|
||||
pub fn derive_maybe_optional_user(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as ItemStruct);
|
||||
|
||||
let name = &input.ident;
|
||||
let mut has_opt_user = false;
|
||||
input.fields.iter().inspect(|f| {
|
||||
if let Some(ident) = f.ident.clone() {
|
||||
match &f.ty {
|
||||
syn::Type::Path(path)
|
||||
if !path.path.segments.is_empty()
|
||||
&& path.path.segments.first().unwrap().ident == "Option" =>
|
||||
{
|
||||
has_opt_user = true && ident == "user";
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let output = quote! {
|
||||
impl crate::templates::MaybeOptionalUser for #name {
|
||||
fn has_optional_user() -> bool {
|
||||
#has_opt_user
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(output)
|
||||
}
|
|
@ -165,7 +165,7 @@ mod test {
|
|||
let s = server().await;
|
||||
let resp = s.get("/logout").await;
|
||||
let body = std::str::from_utf8(resp.bytes()).unwrap().to_string();
|
||||
assert_eq!(body, LogoutGet.to_string());
|
||||
assert_eq!(body, LogoutGet::default().to_string());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -174,7 +174,7 @@ mod test {
|
|||
let resp = s.post("/logout").await;
|
||||
resp.assert_status_ok();
|
||||
let body = std::str::from_utf8(resp.bytes()).unwrap();
|
||||
let default = LogoutPost.to_string();
|
||||
let default = LogoutPost::default().to_string();
|
||||
assert_eq!(body, &default);
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ mod test {
|
|||
|
||||
let resp = s.post("/logout").await;
|
||||
let body = std::str::from_utf8(resp.bytes()).unwrap();
|
||||
let default = LogoutPost.to_string();
|
||||
let default = LogoutPost::default().to_string();
|
||||
assert_eq!(body, &default);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ pub async fn handle_signup_success(
|
|||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
let mut resp = CreateUserSuccess(user.clone()).into_response();
|
||||
let mut resp = CreateUserSuccess { user: user.clone() }.into_response();
|
||||
|
||||
if user.username.is_empty() || id.is_empty() {
|
||||
// redirect to front page if we got here without a valid witch ID
|
||||
|
@ -260,7 +260,7 @@ mod test {
|
|||
|
||||
let resp = server.get(&path).expect_success().await;
|
||||
let body = std::str::from_utf8(resp.bytes()).unwrap();
|
||||
let expected = CreateUserSuccess(user).to_string();
|
||||
let expected = CreateUserSuccess { user }.to_string();
|
||||
assert_eq!(&expected, body);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::User;
|
||||
|
||||
pub trait MaybeOptionalUser {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "signup.html")]
|
||||
pub struct CreateUser {
|
||||
|
@ -11,11 +17,24 @@ pub struct CreateUser {
|
|||
pub email: Option<String>,
|
||||
pub password: String,
|
||||
pub pw_verify: String,
|
||||
user: Option<User>,
|
||||
}
|
||||
impl MaybeOptionalUser for CreateUser {
|
||||
fn has_optional_user() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Template, Default, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "signup_success.html")]
|
||||
pub struct CreateUserSuccess(pub User);
|
||||
pub struct CreateUserSuccess {
|
||||
pub user: User,
|
||||
}
|
||||
impl MaybeOptionalUser for CreateUserSuccess {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "login_post.html")]
|
||||
|
@ -23,6 +42,11 @@ pub struct LoginPost {
|
|||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
impl MaybeOptionalUser for LoginPost {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "login_get.html")]
|
||||
|
@ -30,17 +54,37 @@ pub struct LoginGet {
|
|||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
impl MaybeOptionalUser for LoginGet {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "logout_get.html")]
|
||||
pub struct LogoutGet;
|
||||
impl MaybeOptionalUser for LogoutGet {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "logout_post.html")]
|
||||
pub struct LogoutPost;
|
||||
impl MaybeOptionalUser for LogoutPost {
|
||||
fn has_optional_user() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "index.html")]
|
||||
pub struct MainPage {
|
||||
pub user: Option<User>,
|
||||
}
|
||||
impl MaybeOptionalUser for MainPage {
|
||||
fn has_optional_user() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
any::Any,
|
||||
fmt::{Debug, Display},
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
|
|
@ -12,4 +12,7 @@ pub struct GetWatches {
|
|||
|
||||
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[template(path = "get_search_watches.html")]
|
||||
pub struct GetSearchWatches {}
|
||||
pub struct GetSearchWatches {
|
||||
pub watches: Vec<Watch>,
|
||||
pub user: Option<User>,
|
||||
}
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}{{ title }} - Witch Watch{% endblock %}</title>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
{% block header %}{% endblock %}
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div id="footer">
|
||||
{% block footer %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}{{ title }} - Witch Watch{% endblock %}</title>
|
||||
{% block head %}{% include "header.html" %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
{% block header %}{% endblock %}
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div id="footer">
|
||||
{% block footer %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
22
templates/header.html
Normal file
22
templates/header.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% if Self::has_optional_user() %}
|
||||
|
||||
{% match user %}
|
||||
{% when Some with (usr) %}
|
||||
<div class="header_logged_in">
|
||||
Hello, {{ usr.username }}!
|
||||
</div>
|
||||
<div class="header_signout">
|
||||
<input type="submit" value="sign out?">
|
||||
</form>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="header_logged_out">
|
||||
Heya, why don't you <a href="/login">log in</a> or <a href="/signup">sign up</a>?
|
||||
</div>
|
||||
{% endmatch %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<hr/>
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
{% block title %}Sign Up for Witch Watch, Bish{% endblock %}
|
||||
|
||||
{% block header %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<h1>You did it!</h1>
|
||||
|
||||
<div id="signup_success"><p>
|
||||
{{ self.0 }}
|
||||
{{ self.user }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue