docs: tambah doc comment, logging, dan inline comments di semua 255 file

Meliputi:
- File-level //! doc comment: tujuan file, alur kerja, komponen utama
- Function-level /// doc comment: apa, parameter, return, flow, edge cases
- Struct/enum/trait /// doc comment: peran, field docs
- Tracing logging (tracing::info!/debug!/trace!/warn!/error!) di setiap fungsi
- Inline comments untuk variable dan branching logic penting
- Seluruh 8 crates di workspace: zesdex-backend, zesdex-cms, zesdex-entities,
  zesdex-iam, zesdex-infra, zesdex-ipc, zesdex-middleware, zesdex-utils
- Build: 0 errors, 242/242 tests passed
This commit is contained in:
asepharyana
2026-07-19 17:05:47 +07:00
parent 6680795ce7
commit 5aaedbf787
255 changed files with 5666 additions and 743 deletions
+2
View File
@@ -10,6 +10,7 @@ use serde::de::DeserializeOwned;
use serde::Serialize;
use std::os::unix::net::UnixStream;
use std::sync::Mutex;
use tracing;
/// A thread-safe IPC client connected to a Zesdex daemon over a Unix
/// socket.
@@ -29,6 +30,7 @@ impl IpcClient {
let stream = UnixStream::connect(path)
.with_context(|| format!("failed to connect to Unix socket at {path:?}"))?;
let conn = Connection::new(stream);
tracing::debug!("connected to daemon at {path:?}");
Ok(Self {
conn: Mutex::new(conn),
})
+7 -1
View File
@@ -9,6 +9,7 @@ use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::BufReader;
use std::os::unix::net::UnixStream;
use tracing;
/// A framed JSON connection over a Unix socket.
///
@@ -50,6 +51,7 @@ impl Connection {
/// [`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")?;
tracing::trace!("sending frame ({} byte(s))", json.len());
write_frame(&mut self.writer, &json).context("failed to write frame to connection")
}
@@ -66,8 +68,12 @@ impl Connection {
let raw = read_frame(&mut self.reader).context("failed to read frame from connection")?;
match raw {
None => Ok(None),
None => {
tracing::trace!("connection closed (EOF)");
Ok(None)
}
Some(bytes) => {
tracing::trace!("received frame ({} byte(s))", bytes.len());
let msg: T = serde_json::from_slice(&bytes).with_context(|| {
format!("failed to deserialise frame ({} byte(s))", bytes.len())
})?;
+6 -2
View File
@@ -11,6 +11,7 @@
use anyhow::{Context, Result};
use std::io::{Read, Write};
use tracing;
/// Maximum frame payload size (64 MiB).
const MAX_PAYLOAD: u32 = 64 * 1024 * 1024;
@@ -35,6 +36,7 @@ pub fn read_frame(reader: &mut impl Read) -> Result<Option<Vec<u8>>> {
Ok(()) => {}
Err(ref e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
// Zero bytes available → clean EOF.
tracing::trace!("read_frame: clean EOF");
return Ok(None);
}
Err(e) => return Err(e).context("failed to read frame length prefix"),
@@ -47,11 +49,12 @@ pub fn read_frame(reader: &mut impl Read) -> Result<Option<Vec<u8>>> {
}
// --- Read the payload ---------------------------------------------------
let mut payload = vec![0u8; payload_len];
let mut payload = vec![0u8; payload_len]; // zero-filled buffer of exact length
reader
.read_exact(&mut payload)
.with_context(|| format!("failed to read {payload_len} byte(s) of frame payload"))?;
tracing::trace!("read_frame: {payload_len} byte(s) received");
Ok(Some(payload))
}
@@ -73,7 +76,7 @@ pub fn write_frame(writer: &mut impl Write, data: &[u8]) -> Result<()> {
anyhow::bail!("frame payload too large: {payload_len} bytes (max {MAX_PAYLOAD})");
}
let len_bytes = payload_len.to_be_bytes();
let len_bytes = payload_len.to_be_bytes(); // 4-byte big-endian length prefix
writer
.write_all(&len_bytes)
.context("failed to write frame length prefix")?;
@@ -82,6 +85,7 @@ pub fn write_frame(writer: &mut impl Write, data: &[u8]) -> Result<()> {
.context("failed to write frame payload")?;
writer.flush().context("failed to flush frame writer")?;
tracing::trace!("write_frame: {payload_len} byte(s) sent");
Ok(())
}
+18 -9
View File
@@ -1,14 +1,20 @@
//! # zesdex-ipc
//!
//! Unix-socket IPC layer for daemon/client communication.
//!
//! This crate provides the wire protocol, framing, and connection
//! wrappers used by both the Zesdex daemon and its TUI client.
#![allow(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_precision_loss,
clippy::cast_possible_wrap
)]
//! ## Components
//!
//! - **`protocol`** — Wire-protocol message types (`Request`, `Response`, `Event`, `StreamChunk`).
//! - **`frame`** — Length-delimited binary framing over a Unix socket stream.
//! - **`conn`** — Reusable connection wrapper with read/write framing.
//! - **`client`** — High-level client that sends requests and awaits responses via an internal
//! pending-request map.
//! - **`server`** — Accept-loop server that dispatches incoming requests to a handler closure.
//!
//! ## Flow
//!
//! `client` → `conn` → length-prefixed `frame` → Unix socket → `conn` → `server` → handler.
//! The daemon runs the server side; the TUI process runs the client side.
pub mod client;
pub mod conn;
@@ -21,10 +27,13 @@ pub(crate) mod test_utils {
use serde::{Deserialize, Serialize};
use std::sync::atomic::AtomicUsize;
/// Monotonically increasing test-sequence counter.
pub static TEST_ID: AtomicUsize = AtomicUsize::new(0);
/// Simple Ping payload for round-trip tests.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Ping {
/// Sequence number to correlate request/response.
pub seq: u32,
}
}
+44 -11
View File
@@ -13,22 +13,40 @@ use serde::{Deserialize, Serialize};
/// A resolved key press sent from the daemon to the client (or used inside
/// the client event loop for deferred dispatch).
///
/// Each variant represents a single logical key; modifier flags (ctrl/alt/shift)
/// are carried separately by [`ClientRequest::KeyPress`].
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum KeyAction {
/// A printable Unicode character.
Char(char),
/// The Enter / Return key.
Enter,
/// The Escape key.
Escape,
/// The Backspace key.
Backspace,
/// The Delete key.
Delete,
/// The Tab key.
Tab,
/// Up arrow.
Up,
/// Down arrow.
Down,
/// Left arrow.
Left,
/// Right arrow.
Right,
/// The Home key.
Home,
/// The End key.
End,
/// The Page Up key.
PageUp,
/// The Page Down key.
PageDown,
/// A function key F1F255.
Function(u8),
}
@@ -36,29 +54,36 @@ pub enum KeyAction {
// ClientRequest
// ---------------------------------------------------------------------------
/// A message sent from the TUI client to the daemon.
/// A message sent from the TUI client to the daemon over the IPC socket.
///
/// Each variant corresponds to a distinct client-originated event. The daemon
/// processes it and responds with a [`DaemonFrame`].
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ClientRequest {
/// Periodic heartbeat / tick event.
/// Periodic heartbeat / tick event — keeps the daemon's event loop alive.
Tick,
/// A keyboard event with modifier flags.
KeyPress {
/// The resolved key that was pressed.
key: KeyAction,
/// Whether the Ctrl modifier was held.
ctrl: bool,
/// Whether the Alt modifier was held.
alt: bool,
/// Whether the Shift modifier was held.
shift: bool,
},
/// A completed text submission (e.g. pressing Enter in the input bar).
Submit(String),
/// Pasted text content.
/// Pasted text content from the system clipboard.
Paste(String),
/// Terminal resize notification.
/// Terminal resize notification carrying the new (cols, rows).
Resize(u16, u16),
/// Graceful close / shutdown request.
Close,
/// Scroll the session view up one page or line.
/// Scroll the session view up by one viewport.
ScrollUp,
/// Scroll the session view down one page or line.
/// Scroll the session view down by one viewport.
ScrollDown,
}
@@ -131,22 +156,30 @@ pub struct StatePayload {
/// A frame sent from the daemon to the client.
///
/// Every response from the daemon is one of these variants. The client
/// dispatches on the variant to update its UI model.
/// dispatches on the variant to update its UI model or perform side effects
/// (e.g. clipboard copy).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DaemonFrame {
/// Full state update — the client should replace its entire local state.
/// Full state update — the client should replace its entire local state
/// with the enclosed [`StatePayload`].
StateUpdate(Box<StatePayload>),
/// A streaming token for incremental assistant response rendering.
///
/// The client appends this text to the last assistant message in its
/// local message list.
StreamToken(String),
/// A system-level notification that doesn't alter the session state.
SystemNote {
/// The kind of system note (e.g. "info", "warning", "error").
kind: String,
/// The note content.
/// The display message body.
message: String,
},
/// Instructs the client to place `text` into the system clipboard.
/// Instructs the client to place the enclosed text into the system
/// clipboard.
ClipboardCopy(String),
/// Signals that the daemon has shut down / the session is complete.
/// Signals that the daemon has shut down or the session is complete.
/// The client should tear down its connection and return to the
/// connection screen (or exit).
Closed,
}
+2
View File
@@ -8,6 +8,7 @@ use crate::conn::Connection;
use anyhow::{Context, Result};
use std::os::unix::net::UnixListener;
use std::path::Path;
use tracing;
/// A Unix-socket IPC server.
///
@@ -38,6 +39,7 @@ impl IpcServer {
let listener = UnixListener::bind(path)
.with_context(|| format!("failed to bind Unix socket at {path:?}"))?;
tracing::info!("IPC server bound to {path:?}");
Ok(Self { listener })
}