shit is fucked up, probably abandoning

This commit is contained in:
Joe Ardent 2023-06-13 12:34:54 -07:00
parent 4026bf16b7
commit e310e547f6
14 changed files with 200 additions and 23 deletions

9
Cargo.lock generated
View file

@ -1066,6 +1066,14 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
[[package]]
name = "maybe_optional_user"
version = "0.1.0"
dependencies = [
"quote",
"syn 2.0.18",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.5.0"
@ -2373,6 +2381,7 @@ dependencies = [
"axum-macros", "axum-macros",
"axum-test", "axum-test",
"justerror", "justerror",
"maybe_optional_user",
"password-hash", "password-hash",
"rand_core", "rand_core",
"serde", "serde",

View file

@ -25,6 +25,9 @@ axum-login = { version = "0.5", features = ["sqlite", "sqlx"] }
unicode-segmentation = "1" unicode-segmentation = "1"
async-session = "3" async-session = "3"
# proc macros:
maybe_optional_user = {path = "maybe_optional_user"}
[dev-dependencies] [dev-dependencies]
axum-test = "9.0.0" axum-test = "9.0.0"

46
maybe_optional_user/Cargo.lock generated Normal file
View 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"

View 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"

View 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)
}

View file

@ -165,7 +165,7 @@ mod test {
let s = server().await; let s = server().await;
let resp = s.get("/logout").await; let resp = s.get("/logout").await;
let body = std::str::from_utf8(resp.bytes()).unwrap().to_string(); 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] #[tokio::test]
@ -174,7 +174,7 @@ mod test {
let resp = s.post("/logout").await; let resp = s.post("/logout").await;
resp.assert_status_ok(); resp.assert_status_ok();
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.bytes()).unwrap();
let default = LogoutPost.to_string(); let default = LogoutPost::default().to_string();
assert_eq!(body, &default); assert_eq!(body, &default);
} }
@ -205,7 +205,7 @@ mod test {
let resp = s.post("/logout").await; let resp = s.post("/logout").await;
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.bytes()).unwrap();
let default = LogoutPost.to_string(); let default = LogoutPost::default().to_string();
assert_eq!(body, &default); assert_eq!(body, &default);
} }
} }

View file

@ -122,7 +122,7 @@ pub async fn handle_signup_success(
.unwrap_or_default() .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() { if user.username.is_empty() || id.is_empty() {
// redirect to front page if we got here without a valid witch ID // 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 resp = server.get(&path).expect_success().await;
let body = std::str::from_utf8(resp.bytes()).unwrap(); 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); assert_eq!(&expected, body);
} }

View file

@ -3,6 +3,12 @@ use serde::{Deserialize, Serialize};
use crate::User; use crate::User;
pub trait MaybeOptionalUser {
fn has_optional_user() -> bool {
false
}
}
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "signup.html")] #[template(path = "signup.html")]
pub struct CreateUser { pub struct CreateUser {
@ -11,11 +17,24 @@ pub struct CreateUser {
pub email: Option<String>, pub email: Option<String>,
pub password: String, pub password: String,
pub pw_verify: 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)] #[derive(Debug, Clone, Template, Default, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "signup_success.html")] #[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)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "login_post.html")] #[template(path = "login_post.html")]
@ -23,6 +42,11 @@ pub struct LoginPost {
pub username: String, pub username: String,
pub password: String, pub password: String,
} }
impl MaybeOptionalUser for LoginPost {
fn has_optional_user() -> bool {
false
}
}
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "login_get.html")] #[template(path = "login_get.html")]
@ -30,17 +54,37 @@ pub struct LoginGet {
pub username: String, pub username: String,
pub password: String, pub password: String,
} }
impl MaybeOptionalUser for LoginGet {
fn has_optional_user() -> bool {
false
}
}
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "logout_get.html")] #[template(path = "logout_get.html")]
pub struct LogoutGet; pub struct LogoutGet;
impl MaybeOptionalUser for LogoutGet {
fn has_optional_user() -> bool {
false
}
}
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "logout_post.html")] #[template(path = "logout_post.html")]
pub struct LogoutPost; pub struct LogoutPost;
impl MaybeOptionalUser for LogoutPost {
fn has_optional_user() -> bool {
false
}
}
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "index.html")] #[template(path = "index.html")]
pub struct MainPage { pub struct MainPage {
pub user: Option<User>, pub user: Option<User>,
} }
impl MaybeOptionalUser for MainPage {
fn has_optional_user() -> bool {
true
}
}

View file

@ -1,4 +1,5 @@
use std::{ use std::{
any::Any,
fmt::{Debug, Display}, fmt::{Debug, Display},
time::{SystemTime, UNIX_EPOCH}, time::{SystemTime, UNIX_EPOCH},
}; };

View file

@ -12,4 +12,7 @@ pub struct GetWatches {
#[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)] #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq)]
#[template(path = "get_search_watches.html")] #[template(path = "get_search_watches.html")]
pub struct GetSearchWatches {} pub struct GetSearchWatches {
pub watches: Vec<Watch>,
pub user: Option<User>,
}

View file

@ -1,8 +1,10 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{{ title }} - Witch Watch{% endblock %}</title> <title>{% block title %}{{ title }} - Witch Watch{% endblock %}</title>
{% block head %}{% endblock %} {% block head %}{% include "header.html" %}{% endblock %}
</head> </head>
<body> <body>
<div id="header"> <div id="header">

22
templates/header.html Normal file
View 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/>

View file

@ -2,6 +2,8 @@
{% block title %}Sign Up for Witch Watch, Bish{% endblock %} {% block title %}Sign Up for Witch Watch, Bish{% endblock %}
{% block header %}{% endblock %}
{% block content %} {% block content %}
<p> <p>

View file

@ -7,7 +7,7 @@
<h1>You did it!</h1> <h1>You did it!</h1>
<div id="signup_success"><p> <div id="signup_success"><p>
{{ self.0 }} {{ self.user }}
</p> </p>
</div> </div>