chore: remove unused files and imports

image-uploads
Jef Roosens 2025-01-16 15:06:57 +01:00
parent c7dc68926b
commit 3568365c6f
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
8 changed files with 5 additions and 327 deletions

View File

@ -1,112 +0,0 @@
use std::{fmt::Display, str::FromStr};
use chrono::NaiveDate;
use r2d2_sqlite::rusqlite::{
self,
types::{FromSql, FromSqlError},
Row, ToSql,
};
use serde::{Deserialize, Serialize};
use super::{DbError, DbPool};
pub const EVENT_TYPES: [&str; 1] = ["Watering"];
#[derive(Serialize, Deserialize)]
pub enum EventType {
Watering,
}
impl ToString for EventType {
fn to_string(&self) -> String {
String::from(match self {
Self::Watering => "watering",
})
}
}
#[derive(Debug)]
pub struct ParseEventTypeErr;
impl Display for ParseEventTypeErr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "invalid name")
}
}
impl std::error::Error for ParseEventTypeErr {}
impl FromStr for EventType {
type Err = ParseEventTypeErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"watering" => Ok(Self::Watering),
_ => Err(ParseEventTypeErr),
}
}
}
impl ToSql for EventType {
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(self.to_string().into())
}
}
impl FromSql for EventType {
fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
value
.as_str()?
.parse()
.map_err(|e| FromSqlError::Other(Box::new(e)))
}
}
#[derive(Serialize)]
pub struct Event {
id: i64,
plant_id: i64,
event_type: EventType,
date: NaiveDate,
description: String,
}
impl Event {
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self {
id: row.get("id")?,
plant_id: row.get("plant_id")?,
event_type: row.get("event_type")?,
date: row.get("date")?,
description: row.get("description")?,
})
}
}
#[derive(Deserialize)]
pub struct NewEvent {
plant_id: i64,
event_type: EventType,
date: NaiveDate,
description: String,
}
impl NewEvent {
pub fn insert(self, pool: &DbPool) -> Result<Event, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare(
"insert into events (plant_id, event_type, date, description) values ($1, $2, $3, $4) returning *",
)?;
Ok(stmt.query_row(
(
&self.plant_id,
&self.event_type,
&self.date,
&self.description,
),
Event::from_row,
)?)
}
}

View File

@ -2,21 +2,19 @@ mod models;
mod schema;
use diesel::{
prelude::*,
r2d2::{ConnectionManager, Pool, PooledConnection},
r2d2::{ConnectionManager, Pool},
SqliteConnection,
};
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use std::{error::Error, fmt, path::Path};
pub use models::event::{Event, EventType, NewEvent, EVENT_TYPES};
pub use models::event::{Event, NewEvent, EVENT_TYPES};
pub use models::plant::{NewPlant, Plant};
pub use models::session::Session;
pub use models::user::{NewUser, User};
pub type DbPool = Pool<ConnectionManager<SqliteConnection>>;
pub type DbConn = PooledConnection<ConnectionManager<SqliteConnection>>;
pub type DbResult<T> = Result<T, DbError>;
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");

View File

@ -5,7 +5,7 @@ use argon2::{
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use crate::db::{schema::*, DbConn, DbPool, DbResult};
use crate::db::{schema::*, DbPool, DbResult};
#[derive(Serialize, Deserialize, Clone, Queryable, Selectable)]
#[diesel(table_name = users)]

View File

@ -1,73 +0,0 @@
use r2d2_sqlite::rusqlite::{self, Row};
use serde::{Deserialize, Serialize};
use super::{DbError, DbPool, Event};
#[derive(Serialize)]
pub struct Plant {
id: i64,
name: String,
species: String,
description: String,
}
#[derive(Deserialize)]
pub struct NewPlant {
name: String,
species: String,
description: String,
}
impl Plant {
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self {
id: row.get(0)?,
name: row.get(1)?,
species: row.get(2)?,
description: row.get(3)?,
})
}
pub fn all(pool: &DbPool) -> Result<Vec<Self>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select * from plants")?;
let plants: Result<Vec<_>, _> = stmt.query_map((), Self::from_row)?.collect();
Ok(plants?)
}
pub fn by_id(pool: &DbPool, id: i64) -> Result<Option<Self>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select * from plants where id = $1")?;
match stmt.query_row((id,), |row| Plant::from_row(row)) {
Ok(plant) => Ok(Some(plant)),
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
Err(err) => Err(DbError::Db(err)),
}
}
pub fn events(&self, pool: &DbPool) -> Result<Vec<Event>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select * from events where plant_id = $1")?;
let events: Result<Vec<_>, _> = stmt.query_map((self.id,), Event::from_row)?.collect();
Ok(events?)
}
}
impl NewPlant {
pub fn insert(self, pool: &DbPool) -> Result<Plant, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare(
"insert into plants (name, species, description) values ($1, $2, $3) returning *",
)?;
Ok(stmt.query_row(
(&self.name, &self.species, &self.description),
Plant::from_row,
)?)
}
}

View File

@ -1,39 +0,0 @@
use rand::Rng;
use rusqlite::Row;
use super::{DbError, DbPool, User};
pub struct Session {
pub id: i64,
pub user_id: i32,
}
impl Session {
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self {
id: row.get("id")?,
user_id: row.get("user_id")?,
})
}
pub fn user_from_id(pool: &DbPool, id: i64) -> Result<Option<super::User>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select users.* from sessions inner join users on sessions.user_id = users.id where sessions.id = $1")?;
match stmt.query_row((id,), User::from_row) {
Ok(user) => Ok(Some(user)),
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
Err(err) => Err(DbError::Db(err)),
}
}
pub fn new_for_user(pool: &DbPool, user_id: i64) -> Result<Self, DbError> {
let id: i64 = rand::thread_rng().gen();
let conn = pool.get()?;
let mut stmt =
conn.prepare("insert into sessions (id, user_id) values ($1, $2) returning *")?;
Ok(stmt.query_row((&id, &user_id), Self::from_row)?)
}
}

View File

@ -1,94 +0,0 @@
use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, PasswordHash, PasswordHasher, PasswordVerifier,
};
use rusqlite::Row;
use serde::{Deserialize, Serialize};
use super::{DbError, DbPool};
#[derive(Serialize, Deserialize, Clone)]
pub struct User {
pub id: i64,
pub username: String,
pub password_hash: String,
pub admin: bool,
}
#[derive(Serialize, Deserialize)]
pub struct NewUser {
pub username: String,
pub password: String,
pub admin: bool,
}
impl User {
pub fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self {
id: row.get("id")?,
username: row.get("username")?,
password_hash: row.get("password_hash")?,
admin: row.get("admin")?,
})
}
pub fn by_username(pool: &DbPool, username: impl AsRef<str>) -> Result<Option<Self>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select * from users where username = $1")?;
match stmt.query_row((username.as_ref(),), User::from_row) {
Ok(user) => Ok(Some(user)),
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
Err(err) => Err(DbError::Db(err)),
}
}
pub fn verify_password(&self, password: impl AsRef<str>) -> bool {
let password_hash = PasswordHash::new(&self.password_hash).unwrap();
Argon2::default()
.verify_password(password.as_ref().as_bytes(), &password_hash)
.is_ok()
}
pub fn all(pool: &DbPool) -> Result<Vec<Self>, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("select * from users")?;
let users: Result<Vec<_>, _> = stmt.query_map((), Self::from_row)?.collect();
Ok(users?)
}
pub fn remove_by_username(pool: &DbPool, username: impl AsRef<str>) -> Result<bool, DbError> {
let conn = pool.get()?;
let mut stmt = conn.prepare("delete from users where username = $1")?;
Ok(stmt.execute((username.as_ref(),))? > 0)
}
}
fn hash_password(password: impl AsRef<str>) -> String {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
argon2
.hash_password(password.as_ref().as_bytes(), &salt)
.unwrap()
.to_string()
}
impl NewUser {
pub fn insert(self, pool: &DbPool) -> Result<User, DbError> {
let conn = pool.get()?;
let password_hash = hash_password(&self.password);
let mut stmt = conn.prepare(
"insert into users (username, password_hash, admin) values ($1, $2, $3) returning *",
)?;
Ok(stmt.query_row((&self.username, password_hash, &self.admin), User::from_row)?)
}
}

View File

@ -5,7 +5,6 @@ mod server;
use std::{fs, path::Path, sync::Arc};
use clap::Parser;
use diesel_migrations::{embed_migrations, EmbeddedMigrations};
use tera::Tera;
use tower_http::compression::CompressionLayer;

View File

@ -3,7 +3,7 @@ use axum::{
http::{HeaderMap, StatusCode},
middleware::Next,
response::{Html, IntoResponse, Response},
routing::{get, post},
routing::post,
Form, Router,
};
use axum_extra::extract::{
@ -11,11 +11,10 @@ use axum_extra::extract::{
CookieJar,
};
use serde::Deserialize;
use tera::Context;
use crate::db::{DbError, DbPool, Session, User};
use super::{error::AppError, render_view};
use super::error::AppError;
pub fn logged_in_user(pool: &DbPool, headers: &HeaderMap) -> Result<Option<User>, DbError> {
let jar = CookieJar::from_headers(headers);