Refactor and clean up code across multiple modules
- Simplified token type assignment in OAuth service. - Removed unused session_lock module and re-exported Session from zesdex_entities. - Cleaned up session entity by removing unnecessary comments and code. - Consolidated session handling in HTTP handlers for better readability. - Improved formatting and readability in OAuth repository tests. - Enhanced session lock repository with clearer match statements. - Streamlined session repository error handling. - Refined RNG tests for better clarity. - Adjusted module visibility and organization in lib.rs. - Updated IPC client and connection code for better error handling and clarity. - Improved frame handling in IPC for better readability. - Organized module imports and added test utilities for IPC. - Enhanced database connection error handling. - Simplified JWT token creation error handling. - Improved password verification error handling. - Cleaned up state management code for better readability. - Refactored middleware for session authentication and rate limiting. - Simplified clipboard utility for better error handling. - Enhanced logging initialization for better error reporting. - Improved pagination utility with clearer method annotations. - Cleaned up sanitization functions for filenames and paths. - Enhanced slug generation functions for better clarity and usability.
This commit is contained in:
@@ -4,13 +4,6 @@
|
||||
//! [`IpcClient`] wraps a [`Connection`] behind a [`Mutex`] so it can be
|
||||
//! shared across threads (e.g. the TUI event loop and the render task).
|
||||
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_possible_wrap
|
||||
)]
|
||||
|
||||
use crate::conn::Connection;
|
||||
use anyhow::{Context, Result};
|
||||
use serde::de::DeserializeOwned;
|
||||
@@ -43,6 +36,11 @@ impl IpcClient {
|
||||
|
||||
/// Serialise `msg` to JSON and send it as a length-prefixed frame.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the internal mutex is poisoned (a previous operation
|
||||
/// panicked while holding the lock).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Delegates to the underlying [`Connection::send`].
|
||||
@@ -58,6 +56,11 @@ impl IpcClient {
|
||||
///
|
||||
/// Returns `Ok(None)` on clean EOF (daemon closed the connection).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the internal mutex is poisoned (a previous operation
|
||||
/// panicked while holding the lock).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Delegates to the underlying [`Connection::receive`].
|
||||
@@ -73,17 +76,13 @@ impl IpcClient {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::os::unix::net::UnixListener;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
struct Ping {
|
||||
seq: u32,
|
||||
}
|
||||
use crate::test_utils::Ping;
|
||||
|
||||
#[test]
|
||||
fn connect_and_round_trip() {
|
||||
let dir = std::env::temp_dir().join(format!("zesdex-ipc-test-{}", std::process::id()));
|
||||
let id = crate::test_utils::TEST_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||
let dir = std::env::temp_dir().join(format!("zesdex-ipc-test-{}-{}", std::process::id(), id));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let sock_path = dir.join("test.sock");
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
//! [`Connection`] pairs a buffered reader with a raw writer and exposes
|
||||
//! `send` / `receive` for framed JSON messages.
|
||||
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_possible_wrap
|
||||
)]
|
||||
|
||||
use crate::frame::{read_frame, write_frame};
|
||||
use anyhow::{Context, Result};
|
||||
use serde::de::DeserializeOwned;
|
||||
@@ -30,6 +23,12 @@ pub struct Connection {
|
||||
|
||||
impl Connection {
|
||||
/// Create a new `Connection` from an already-connected [`UnixStream`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `UnixStream::try_clone` fails — this should never happen on
|
||||
/// Linux (it calls `dup(2)`).
|
||||
#[must_use]
|
||||
pub fn new(stream: UnixStream) -> Self {
|
||||
// Clone the stream so that reader and writer can reference separate
|
||||
// file-descriptor handles. `UnixStream::try_clone` is infallible on
|
||||
@@ -50,10 +49,8 @@ impl Connection {
|
||||
/// Delegates to [`serde_json::to_vec`] for serialisation and
|
||||
/// [`write_frame`] for writing.
|
||||
pub fn send<T: Serialize>(&mut self, msg: &T) -> Result<()> {
|
||||
let json =
|
||||
serde_json::to_vec(msg).context("failed to serialise message to JSON")?;
|
||||
write_frame(&mut self.writer, &json)
|
||||
.context("failed to write frame to connection")
|
||||
let json = serde_json::to_vec(msg).context("failed to serialise message to JSON")?;
|
||||
write_frame(&mut self.writer, &json).context("failed to write frame to connection")
|
||||
}
|
||||
|
||||
/// Read one framed JSON message and deserialise it.
|
||||
@@ -66,19 +63,14 @@ impl Connection {
|
||||
/// Delegates to [`read_frame`] for reading and
|
||||
/// [`serde_json::from_slice`] for deserialisation.
|
||||
pub fn receive<T: DeserializeOwned>(&mut self) -> Result<Option<T>> {
|
||||
let raw = read_frame(&mut self.reader)
|
||||
.context("failed to read frame from connection")?;
|
||||
let raw = read_frame(&mut self.reader).context("failed to read frame from connection")?;
|
||||
|
||||
match raw {
|
||||
None => Ok(None),
|
||||
Some(bytes) => {
|
||||
let msg: T = serde_json::from_slice(&bytes)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to deserialise frame ({} byte(s))",
|
||||
bytes.len()
|
||||
)
|
||||
})?;
|
||||
let msg: T = serde_json::from_slice(&bytes).with_context(|| {
|
||||
format!("failed to deserialise frame ({} byte(s))", bytes.len())
|
||||
})?;
|
||||
Ok(Some(msg))
|
||||
}
|
||||
}
|
||||
@@ -99,12 +91,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
struct Ping {
|
||||
seq: u32,
|
||||
}
|
||||
use crate::test_utils::Ping;
|
||||
|
||||
/// Helper: create a pair of connected `Connection` values via a
|
||||
/// Unix socket pair.
|
||||
@@ -132,8 +119,7 @@ mod tests {
|
||||
// Since we dropped right, left's reads should eventually get EOF.
|
||||
// But with a socket pair, dropping one end signals EOF on the other.
|
||||
drop(left); // drop left too — we'll test EOF on a fresh pair
|
||||
let (mut a, _b) = pair();
|
||||
drop(_b);
|
||||
let (mut a, _) = pair();
|
||||
let result: Option<Ping> = a.receive().unwrap();
|
||||
assert!(result.is_none());
|
||||
}
|
||||
|
||||
@@ -50,9 +50,7 @@ pub fn read_frame(reader: &mut impl Read) -> Result<Option<Vec<u8>>> {
|
||||
let payload_len = u32::from_be_bytes(len_buf) as usize;
|
||||
|
||||
if payload_len > MAX_PAYLOAD as usize {
|
||||
anyhow::bail!(
|
||||
"frame payload too large: {payload_len} bytes (max {MAX_PAYLOAD})"
|
||||
);
|
||||
anyhow::bail!("frame payload too large: {payload_len} bytes (max {MAX_PAYLOAD})");
|
||||
}
|
||||
|
||||
// --- Read the payload ---------------------------------------------------
|
||||
@@ -79,9 +77,7 @@ pub fn write_frame(writer: &mut impl Write, data: &[u8]) -> Result<()> {
|
||||
.context("payload length exceeds u32 range")?;
|
||||
|
||||
if payload_len > MAX_PAYLOAD {
|
||||
anyhow::bail!(
|
||||
"frame payload too large: {payload_len} bytes (max {MAX_PAYLOAD})"
|
||||
);
|
||||
anyhow::bail!("frame payload too large: {payload_len} bytes (max {MAX_PAYLOAD})");
|
||||
}
|
||||
|
||||
let len_bytes = payload_len.to_be_bytes();
|
||||
@@ -91,9 +87,7 @@ pub fn write_frame(writer: &mut impl Write, data: &[u8]) -> Result<()> {
|
||||
writer
|
||||
.write_all(data)
|
||||
.context("failed to write frame payload")?;
|
||||
writer
|
||||
.flush()
|
||||
.context("failed to flush frame writer")?;
|
||||
writer.flush().context("failed to flush frame writer")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -10,8 +10,21 @@
|
||||
clippy::cast_possible_wrap
|
||||
)]
|
||||
|
||||
pub mod protocol;
|
||||
pub mod frame;
|
||||
pub mod conn;
|
||||
pub mod client;
|
||||
pub mod conn;
|
||||
pub mod frame;
|
||||
pub mod protocol;
|
||||
pub mod server;
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_utils {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
|
||||
pub static TEST_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Ping {
|
||||
pub seq: u32,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,16 +79,12 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
struct Ping {
|
||||
seq: u32,
|
||||
}
|
||||
use crate::test_utils::Ping;
|
||||
|
||||
#[test]
|
||||
fn bind_and_accept_one() {
|
||||
let dir = std::env::temp_dir().join(format!("zesdex-ipc-test-{}", std::process::id()));
|
||||
let id = crate::test_utils::TEST_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||
let dir = std::env::temp_dir().join(format!("zesdex-ipc-test-{}-{}", std::process::id(), id));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let sock_path = dir.join("server_test.sock");
|
||||
|
||||
Reference in New Issue
Block a user