WIP deisel stuff

This commit is contained in:
Daniel Flanagan 2023-11-12 09:56:23 -06:00
parent 0dae560a39
commit 827a519ca5
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
13 changed files with 429 additions and 58 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/target
/.direnv
*.sqlitedb

251
Cargo.lock generated
View file

@ -146,6 +146,107 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "deadpool"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490"
dependencies = [
"async-trait",
"deadpool-runtime",
"num_cpus",
"serde",
"tokio",
]
[[package]]
name = "deadpool-diesel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa8404d25ddc6cb0676d4a863bbd007613ee3fffb54db23e0e6341e1fe61c3e"
dependencies = [
"deadpool",
"deadpool-sync",
"diesel",
]
[[package]]
name = "deadpool-runtime"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49"
dependencies = [
"tokio",
]
[[package]]
name = "deadpool-sync"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8db70494c13cae4ce67b4b4dafdaf828cf0df7237ab5b9e2fcabee4965d0a0a"
dependencies = [
"deadpool-runtime",
"tracing",
]
[[package]]
name = "deranged"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
dependencies = [
"powerfmt",
]
[[package]]
name = "diesel"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2268a214a6f118fce1838edba3d1561cf0e78d8de785475957a580a7f8c69d33"
dependencies = [
"diesel_derives",
"libsqlite3-sys",
"time",
]
[[package]]
name = "diesel_derives"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44"
dependencies = [
"diesel_table_macro_syntax",
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "diesel_migrations"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac"
dependencies = [
"diesel",
"migrations_internals",
"migrations_macros",
]
[[package]]
name = "diesel_table_macro_syntax"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
dependencies = [
"syn 2.0.39",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "fnv"
version = "1.0.7"
@ -206,6 +307,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
[[package]]
name = "hermit-abi"
version = "0.3.3"
@ -275,6 +382,16 @@ dependencies = [
"want",
]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.9"
@ -293,6 +410,16 @@ version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "libsqlite3-sys"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
dependencies = [
"pkg-config",
"vcpkg",
]
[[package]]
name = "lock_api"
version = "0.4.11"
@ -315,6 +442,10 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"deadpool",
"deadpool-diesel",
"diesel",
"diesel_migrations",
"maud",
"serde",
"tokio",
@ -367,6 +498,27 @@ version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "migrations_internals"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada"
dependencies = [
"serde",
"toml",
]
[[package]]
name = "migrations_macros"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08"
dependencies = [
"migrations_internals",
"proc-macro2",
"quote",
]
[[package]]
name = "mime"
version = "0.3.17"
@ -505,6 +657,18 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -665,6 +829,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -759,6 +932,35 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
dependencies = [
"deranged",
"itoa",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
dependencies = [
"time-core",
]
[[package]]
name = "tokio"
version = "1.34.0"
@ -802,6 +1004,40 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -958,6 +1194,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
@ -1066,3 +1308,12 @@ name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "winnow"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b"
dependencies = [
"memchr",
]

View file

@ -6,9 +6,13 @@ edition = "2021"
[dependencies]
anyhow = "1.0.75"
axum = "0.6.20"
deadpool = "0.10.0"
deadpool-diesel = { version = "0.5.0", features = ["rt_tokio_1", "sqlite", "tracing", "serde"] }
diesel = { version = "2.1.3", features = ["sqlite"] }
diesel_migrations = { version = "2.1.0", features = ["sqlite"] }
maud = "0.25.0"
serde = { version = "1.0.192", features = ["derive"] }
tokio = { version = "1.34.0", features = ["full"] }
tokio = { version = "1.34.0", features = ["full", "macros", "rt-multi-thread"] }
tower-http = { version = "0.4.4", features = ["fs"] }
tower-livereload = "0.8.2"
tracing = "0.1.40"

0
assets/favicon.svg Normal file
View file

View file

@ -16,18 +16,7 @@ html {
text-size-adjust: none;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd {
body {
margin: 0;
}
@ -53,6 +42,7 @@ h4,
h5,
h6,
button,
.button,
input,
label {
line-height: 1.1;
@ -73,6 +63,7 @@ picture {
input,
button,
.button,
textarea,
select {
font: inherit;
@ -87,10 +78,6 @@ textarea:not([rows]) {
scroll-margin-block: 5ex;
}
a[class] {
color: currentColor;
}
/* end reset */
/* global classes */
@ -103,6 +90,10 @@ a[class] {
flex-direction: column;
}
.gap {
gap: 1ex;
}
/* end global classes */
:root {
@ -175,6 +166,11 @@ a[class] {
}
}
ul,
ol {
padding-left: 2ex;
}
html {
background-color: var(--bg);
color: var(--text);
@ -182,11 +178,15 @@ html {
font-size: 16px;
}
body>header h1 {
margin: 0;
}
body>header {
justify-content: space-between;
/* border-bottom: solid 1px var(--bg2); */
background-color: var(--bg);
box-shadow: 0 -1px 1ex var(--Crust);
background-color: color-mix(in srgb, var(--Surface0) 30%, transparent);
box-shadow: 0 -1px 1ex var(--Mantle);
}
body>header>nav {
@ -196,13 +196,33 @@ body>header>nav {
body>header a:not([class]) {
display: flex;
align-items: center;
padding: 1ex;
padding: 1ex 2ex;
transition: color 0.1s ease-out, background-color 0.1s ease-out;
text-decoration: none;
color: var(--primary);
gap: 0.5ex;
}
main.prose {
padding: 1ex;
max-width: 80ch;
}
.button {
background-color: var(--Surface0);
padding: 1ex 2ex;
text-decoration: none;
color: currentColor;
box-shadow: 0 -1px 1px var(--Mantle);
border-radius: 2px;
}
body>header a:hover {
background-color: var(--primary);
color: var(--bg);
}
.bg-primary {
background-color: var(--primary);
color: var(--bg);
}

3
build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("cargo:rerun-if-changed=./migrations");
}

1
data/.keep Normal file
View file

@ -0,0 +1 @@

6
diesel.toml Normal file
View file

@ -0,0 +1,6 @@
[print_schema]
file = "src/schema.rs"
custom_type_derives = ["diesel::query_builder::QueryId"]
[migrations_directory]
dir = "migrations"

View file

@ -33,6 +33,7 @@
in {
packages.default = naersk.buildPackage {
src = ./.;
buildInputs = with pkgs; [sqlite];
};
formatter = pkgs.alejandra;
checks = {
@ -42,14 +43,22 @@
devShell = with pkgs;
mkShell {
buildInputs = [
hurl
toolchain
rustfmt
rustPackages.clippy
rust-analyzer
nodePackages_latest.vscode-langservers-extracted
# dedupe from package inputs?
sqlite
diesel-cli
hurl
];
RUST_SRC_PATH = rustPlatform.rustLibSrc;
shellHook = ''
export DATABASE_URL="sqlite://./data/lyrs.sqlitedb";
'';
};
});
}

View file

@ -0,0 +1 @@
drop table users

View file

@ -0,0 +1,5 @@
create table users (
id text primary key,
name text,
hashed_password text
)

View file

@ -1,53 +1,83 @@
//! lyrs entrypoint
use axum::{response::Html, routing::get, Router};
use maud::html;
use std::net::SocketAddr;
use axum::{http::StatusCode, response::Html, routing::get, Router};
use deadpool_diesel::sqlite::{Manager, Pool, Runtime};
use diesel::sqlite::Sqlite;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use maud::{html, PreEscaped};
use std::{env, net::SocketAddr};
use tower_http::services::ServeDir;
use tower_livereload::LiveReloadLayer;
use tracing::{info, instrument, trace};
use tracing_subscriber::{
filter::{Directive, LevelFilter},
EnvFilter,
};
use tracing::{info, instrument, span, trace, Level};
use tracing_subscriber::{filter::LevelFilter, EnvFilter};
#[instrument]
fn setup_trace_logger() {
let default_filter: Result<EnvFilter, tracing_subscriber::filter::ParseError> =
Ok(EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.parse("info")
.unwrap());
let default_directive: Result<Directive, tracing_subscriber::filter::ParseError> =
"lyrs=trace".parse();
if default_directive.is_err() {
println!("{:?}", default_directive);
}
let filter = EnvFilter::try_from_env("LOG_FILTER")
.or(default_filter)
.unwrap()
.add_directive(LevelFilter::INFO.into())
.add_directive("lyrs=trace".parse().unwrap());
let filter = EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.parse_lossy("info,lyrs=trace");
tracing_subscriber::fmt().with_env_filter(filter).init();
trace!("Starting...");
}
fn router() -> Router {
// struct State {
// pub pool: Pool,
// }
fn run_migrations(
connection: &mut impl MigrationHarness<Sqlite>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
// This will run the necessary migrations.
//
// See the documentation for `MigrationHarness` for
// all available methods.
connection.run_pending_migrations(MIGRATIONS)?;
Ok(())
}
#[instrument]
async fn router() -> Result<Router, anyhow::Error> {
let app_router = Router::new()
.route("/hello-world", get(greet_world))
.route("/hello-world-text", get(greet_world_text));
let assets_dir = ServeDir::new("./assets");
Router::new()
let pool;
let dbspan = span!(Level::WARN, "database_setup");
{
let _s = dbspan.enter();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = Manager::new(database_url, Runtime::Tokio1);
pool = Pool::builder(manager).max_size(8).build().unwrap();
info!("Database pool creation complete!");
let conn = pool.get().await?;
let mspan = span!(Level::INFO, "migrations");
{
let _s = mspan.enter();
let _ = conn
.interact(|c| run_migrations(c))
.await
.expect("Failed to run migrations");
info!("Migrations completed!");
}
}
// let state = Arc::new(State { pool });
Ok(Router::new()
.fallback(|| async { (StatusCode::NOT_FOUND, "404 page not found") })
.nest("/app", app_router)
.nest_service("/assets", assets_dir)
.route("/", get(index))
.layer(LiveReloadLayer::new())
.layer(LiveReloadLayer::new()))
// .with_state(state))
}
async fn listen(r: Router) {
@ -59,37 +89,68 @@ async fn listen(r: Router) {
.unwrap();
}
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
#[tokio::main]
async fn main() {
async fn main() -> Result<(), anyhow::Error> {
setup_trace_logger();
listen(router()).await;
listen(router().await?).await;
Ok(())
}
// feather icons
const FEATHER_ICON_LAYOUT: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layout"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line></svg>"#;
const FEATHER_ICON_LOGIN: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-in"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>"#;
#[instrument]
async fn index() -> Html<String> {
Html(
html! {
head {
link rel="stylesheet" href="/assets/styles.css" {}
link rel="icon" href="/assets/favicon.svg" {}
}
header class="flex" {
nav class="flex" {
h1 {
a href="/" { "lyrs" }
}
ul class="flex"
{
a href="/login" { "Login" }
}
// ul class="flex"
// {
// a href="/login" { "Login" }
// }
}
nav class="flex" {
ul class="flex"
{
a href="/register" { "Register" }
a href="/login" { "Login" }
a href="/dashboard" {
(PreEscaped(FEATHER_ICON_LAYOUT))
"Dashboard"
}
a href="/login" {
(PreEscaped(FEATHER_ICON_LOGIN))
"Login"
}
}
}
}
main class="prose" {
h1 { "Manage live lyrics and music displays" }
p { "Stop struggling to share the same messy set of PowerPoint files or Google Presentations. Make editing and controlling your live lyrics and music displays easy and simple." }
ul {
li { "Live collaboration with your team" }
li { "Fully compatible with any device" }
li { "Simple workflow" }
li { "Dark theme and light theme" }
li { "Generous free plan" }
li { "Lightweight and fast" }
}
section class="flex gap" {
a class="button bg-primary" href="/register/anonymous" { "Try now" }
a class="button" href="/login" { "Login" }
}
}
}
.into_string(),
)

9
src/schema.rs Normal file
View file

@ -0,0 +1,9 @@
// @generated automatically by Diesel CLI.
diesel::table! {
users (id) {
id -> Nullable<Text>,
name -> Nullable<Text>,
hashed_password -> Nullable<Text>,
}
}