Update dependencies and desktop components
This commit is contained in:
parent
9f641d3504
commit
20232432c6
6 changed files with 52 additions and 143 deletions
22
Cargo.toml
22
Cargo.toml
|
|
@ -46,23 +46,5 @@ desktop-tray = ["dep:ksni", "dep:trayicon"]
|
|||
[build-dependencies]
|
||||
tauri-build = "2"
|
||||
|
||||
[lints.rust]
|
||||
unused_imports = "warn"
|
||||
unused_variables = "warn"
|
||||
unused_mut = "warn"
|
||||
unsafe_code = "deny"
|
||||
missing_debug_implementations = "warn"
|
||||
|
||||
[lints.clippy]
|
||||
all = "warn"
|
||||
pedantic = "warn"
|
||||
nursery = "warn"
|
||||
cargo = "warn"
|
||||
unwrap_used = "warn"
|
||||
expect_used = "warn"
|
||||
panic = "warn"
|
||||
todo = "warn"
|
||||
# Disabled: Tauri commands require owned types (Window) that cannot be passed by reference
|
||||
needless_pass_by_value = "allow"
|
||||
# Disabled: transitive dependencies we cannot control
|
||||
multiple_crate_versions = "allow"
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
51
PROMPT.md
51
PROMPT.md
|
|
@ -26,7 +26,11 @@
|
|||
❌ NEVER leave dead code - DELETE it or IMPLEMENT it
|
||||
❌ NEVER use approximate constants (3.14159) - use std::f64::consts::PI
|
||||
❌ NEVER silence clippy in code - FIX THE CODE or configure in Cargo.toml
|
||||
❌ NEVER add comments explaining what code does - code must be self-documenting
|
||||
❌ NEVER add comments - code must be self-documenting via types and naming
|
||||
❌ NEVER add file header comments (//! or /*!) - no module docs
|
||||
❌ NEVER add function doc comments (///) - types are the documentation
|
||||
❌ NEVER add ASCII art or banners in code
|
||||
❌ NEVER add TODO/FIXME/HACK comments - fix it or delete it
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -104,6 +108,50 @@ struct MyStruct { }
|
|||
struct MyStruct { }
|
||||
```
|
||||
|
||||
### Zero Comments Policy
|
||||
|
||||
```rust
|
||||
// ❌ WRONG - any comments
|
||||
/// Returns the user's full name
|
||||
fn get_full_name(&self) -> String { }
|
||||
|
||||
// Validate input before processing
|
||||
fn process(data: &str) { }
|
||||
|
||||
//! This module handles user authentication
|
||||
|
||||
// ✅ CORRECT - self-documenting code, no comments
|
||||
fn full_name(&self) -> String { }
|
||||
|
||||
fn process_validated_input(data: &str) { }
|
||||
```
|
||||
|
||||
**Why zero comments in the LLM era:**
|
||||
|
||||
With Rust's strong type system, **zero comments** is the right approach:
|
||||
|
||||
**Rust already provides:**
|
||||
- Type signatures = documentation
|
||||
- `Result<T, E>` = documents errors
|
||||
- `Option<T>` = documents nullability
|
||||
- Trait bounds = documents requirements
|
||||
- Expressive naming = self-documenting
|
||||
|
||||
**LLMs can:**
|
||||
- Infer intent from code structure
|
||||
- Understand patterns without comments
|
||||
- Generate docs on-demand if needed
|
||||
|
||||
**Comments become:**
|
||||
- Stale/wrong (code changes, comments don't)
|
||||
- Noise that obscures actual logic
|
||||
- Maintenance burden
|
||||
|
||||
**Rust community stance:**
|
||||
- Rustdoc is for *public API* crates (libraries published to crates.io)
|
||||
- Internal/application code: types + good names > comments
|
||||
- The Rust book emphasizes "code should be self-documenting"
|
||||
|
||||
---
|
||||
|
||||
## Weekly Maintenance - EVERY MONDAY
|
||||
|
|
@ -491,6 +539,7 @@ cargo test
|
|||
## Remember
|
||||
|
||||
- **ZERO WARNINGS** - Every clippy warning must be fixed
|
||||
- **ZERO COMMENTS** - No comments, no doc comments, no file headers, no ASCII art
|
||||
- **NO ALLOW IN CODE** - Never use #[allow()] in source files
|
||||
- **CARGO.TOML EXCEPTIONS OK** - Disable lints with false positives in Cargo.toml with comment
|
||||
- **NO DEAD CODE** - Delete unused code, never prefix with _
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
//! Drive/File System commands for Tauri
|
||||
//!
|
||||
//! Provides native file system access for the desktop app.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
|
|
@ -17,11 +14,6 @@ pub struct FileItem {
|
|||
pub size: Option<u64>,
|
||||
}
|
||||
|
||||
/// Lists files in the specified directory.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path does not exist or cannot be read.
|
||||
#[tauri::command]
|
||||
pub fn list_files(path: &str) -> Result<Vec<FileItem>, String> {
|
||||
let base_path = Path::new(path);
|
||||
|
|
@ -66,11 +58,6 @@ pub fn list_files(path: &str) -> Result<Vec<FileItem>, String> {
|
|||
Ok(files)
|
||||
}
|
||||
|
||||
/// Uploads a file from source to destination with progress events.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the source file cannot be read or the destination cannot be written.
|
||||
#[tauri::command]
|
||||
pub fn upload_file(window: Window, src_path: &str, dest_path: &str) -> Result<(), String> {
|
||||
let src = PathBuf::from(src_path);
|
||||
|
|
@ -113,11 +100,6 @@ pub fn upload_file(window: Window, src_path: &str, dest_path: &str) -> Result<()
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates a new folder at the specified path.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the folder already exists or cannot be created.
|
||||
#[tauri::command]
|
||||
pub fn create_folder(path: &str, name: &str) -> Result<(), String> {
|
||||
let full_path = Path::new(path).join(name);
|
||||
|
|
@ -130,11 +112,6 @@ pub fn create_folder(path: &str, name: &str) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Deletes a file or directory at the specified path.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path does not exist or cannot be deleted.
|
||||
#[tauri::command]
|
||||
pub fn delete_path(path: &str) -> Result<(), String> {
|
||||
let target = Path::new(path);
|
||||
|
|
@ -152,11 +129,6 @@ pub fn delete_path(path: &str) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the user's home directory path.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the home directory cannot be determined.
|
||||
#[tauri::command]
|
||||
pub fn get_home_dir() -> Result<String, String> {
|
||||
dirs::home_dir()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
//! Sync module for cloud storage synchronization using rclone.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
|
@ -56,7 +55,6 @@ impl Default for SyncConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the current sync status.
|
||||
#[tauri::command]
|
||||
#[must_use]
|
||||
pub fn get_sync_status() -> SyncStatus {
|
||||
|
|
@ -81,11 +79,6 @@ pub fn get_sync_status() -> SyncStatus {
|
|||
}
|
||||
}
|
||||
|
||||
/// Starts the sync process with the given configuration.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if sync is already running, directory creation fails, or rclone fails to start.
|
||||
#[tauri::command]
|
||||
pub fn start_sync(window: Window, config: Option<SyncConfig>) -> Result<SyncStatus, String> {
|
||||
let config = config.unwrap_or_default();
|
||||
|
|
@ -166,11 +159,6 @@ pub fn start_sync(window: Window, config: Option<SyncConfig>) -> Result<SyncStat
|
|||
})
|
||||
}
|
||||
|
||||
/// Stops the currently running sync process.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if no sync process is running.
|
||||
#[tauri::command]
|
||||
pub fn stop_sync() -> Result<SyncStatus, String> {
|
||||
let mut process_guard = RCLONE_PROCESS
|
||||
|
|
@ -197,11 +185,6 @@ pub fn stop_sync() -> Result<SyncStatus, String> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Configures an rclone remote for S3-compatible storage.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if rclone configuration fails.
|
||||
#[tauri::command]
|
||||
pub fn configure_remote(
|
||||
remote_name: &str,
|
||||
|
|
@ -242,11 +225,6 @@ pub fn configure_remote(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks if rclone is installed and returns its version.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if rclone is not installed or the check fails.
|
||||
#[tauri::command]
|
||||
pub fn check_rclone_installed() -> Result<String, String> {
|
||||
let output = Command::new("rclone")
|
||||
|
|
@ -269,11 +247,6 @@ pub fn check_rclone_installed() -> Result<String, String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Lists all configured rclone remotes.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if rclone fails to list remotes.
|
||||
#[tauri::command]
|
||||
pub fn list_remotes() -> Result<Vec<String>, String> {
|
||||
let output = Command::new("rclone")
|
||||
|
|
@ -293,7 +266,6 @@ pub fn list_remotes() -> Result<Vec<String>, String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the default sync folder path.
|
||||
#[tauri::command]
|
||||
#[must_use]
|
||||
pub fn get_sync_folder() -> String {
|
||||
|
|
@ -303,11 +275,6 @@ pub fn get_sync_folder() -> String {
|
|||
)
|
||||
}
|
||||
|
||||
/// Sets the sync folder path, creating it if necessary.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the directory cannot be created or the path is not a directory.
|
||||
#[tauri::command]
|
||||
pub fn set_sync_folder(path: &str) -> Result<(), String> {
|
||||
let path = PathBuf::from(path);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
//! Tray manager for desktop application.
|
||||
//!
|
||||
//! Provides system tray functionality for different operating modes.
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
/// Manages the system tray icon and its interactions.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TrayManager {
|
||||
hostname: Arc<RwLock<Option<String>>>,
|
||||
|
|
@ -15,32 +11,22 @@ pub struct TrayManager {
|
|||
tray_active: Arc<RwLock<bool>>,
|
||||
}
|
||||
|
||||
/// The running mode of the application.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum RunningMode {
|
||||
/// Full server mode with all services.
|
||||
Server,
|
||||
/// Desktop mode with UI and local services.
|
||||
Desktop,
|
||||
/// Client mode connecting to remote server.
|
||||
Client,
|
||||
}
|
||||
|
||||
/// Events that can be triggered from the tray menu.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TrayEvent {
|
||||
/// Open the main application window.
|
||||
Open,
|
||||
/// Open settings dialog.
|
||||
Settings,
|
||||
/// Show about dialog.
|
||||
About,
|
||||
/// Quit the application.
|
||||
Quit,
|
||||
}
|
||||
|
||||
impl TrayManager {
|
||||
/// Creates a new tray manager with default settings.
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
|
@ -50,7 +36,6 @@ impl TrayManager {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a new tray manager with the specified running mode.
|
||||
#[must_use]
|
||||
pub fn with_mode(mode: RunningMode) -> Self {
|
||||
Self {
|
||||
|
|
@ -60,11 +45,6 @@ impl TrayManager {
|
|||
}
|
||||
}
|
||||
|
||||
/// Starts the tray manager based on the running mode.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the tray initialization fails.
|
||||
pub async fn start(&self) -> Result<()> {
|
||||
match self.running_mode {
|
||||
RunningMode::Desktop => {
|
||||
|
|
@ -129,7 +109,6 @@ impl TrayManager {
|
|||
);
|
||||
}
|
||||
|
||||
/// Returns a string representation of the current running mode.
|
||||
#[must_use]
|
||||
pub fn get_mode_string(&self) -> String {
|
||||
match self.running_mode {
|
||||
|
|
@ -139,11 +118,6 @@ impl TrayManager {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates the tray status message.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the status update fails.
|
||||
pub async fn update_status(&self, status: &str) -> Result<()> {
|
||||
let active = self.tray_active.read().await;
|
||||
let is_active = *active;
|
||||
|
|
@ -155,11 +129,6 @@ impl TrayManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Sets the tray tooltip text.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if setting the tooltip fails.
|
||||
pub async fn set_tooltip(&self, tooltip: &str) -> Result<()> {
|
||||
let active = self.tray_active.read().await;
|
||||
let is_active = *active;
|
||||
|
|
@ -171,11 +140,6 @@ impl TrayManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Shows a desktop notification.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if showing the notification fails.
|
||||
pub async fn show_notification(&self, title: &str, body: &str) -> Result<()> {
|
||||
let active = self.tray_active.read().await;
|
||||
let is_active = *active;
|
||||
|
|
@ -204,23 +168,16 @@ impl TrayManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the current hostname.
|
||||
pub async fn get_hostname(&self) -> Option<String> {
|
||||
let hostname = self.hostname.read().await;
|
||||
hostname.clone()
|
||||
}
|
||||
|
||||
/// Sets the hostname.
|
||||
pub async fn set_hostname(&self, new_hostname: String) {
|
||||
let mut hostname = self.hostname.write().await;
|
||||
*hostname = Some(new_hostname);
|
||||
}
|
||||
|
||||
/// Stops the tray manager.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if stopping fails.
|
||||
pub async fn stop(&self) {
|
||||
let mut active = self.tray_active.write().await;
|
||||
*active = false;
|
||||
|
|
@ -228,7 +185,6 @@ impl TrayManager {
|
|||
log::info!("Tray manager stopped");
|
||||
}
|
||||
|
||||
/// Returns whether the tray is currently active.
|
||||
pub async fn is_active(&self) -> bool {
|
||||
let active = self.tray_active.read().await;
|
||||
let result = *active;
|
||||
|
|
@ -236,7 +192,6 @@ impl TrayManager {
|
|||
result
|
||||
}
|
||||
|
||||
/// Handles a tray event and performs the appropriate action.
|
||||
pub fn handle_event(&self, event: TrayEvent) {
|
||||
let mode = self.get_mode_string();
|
||||
match event {
|
||||
|
|
@ -262,27 +217,20 @@ impl Default for TrayManager {
|
|||
}
|
||||
}
|
||||
|
||||
/// Monitors the status of services.
|
||||
#[derive(Debug)]
|
||||
pub struct ServiceMonitor {
|
||||
services: Vec<ServiceStatus>,
|
||||
}
|
||||
|
||||
/// Status of a monitored service.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct ServiceStatus {
|
||||
/// Service name.
|
||||
pub name: String,
|
||||
/// Whether the service is running.
|
||||
pub running: bool,
|
||||
/// Service port number.
|
||||
pub port: u16,
|
||||
/// Service URL.
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
impl ServiceMonitor {
|
||||
/// Creates a new service monitor with default services.
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
|
@ -303,7 +251,6 @@ impl ServiceMonitor {
|
|||
}
|
||||
}
|
||||
|
||||
/// Adds a service to monitor.
|
||||
pub fn add_service(&mut self, name: &str, port: u16) {
|
||||
self.services.push(ServiceStatus {
|
||||
name: name.to_string(),
|
||||
|
|
@ -313,7 +260,6 @@ impl ServiceMonitor {
|
|||
});
|
||||
}
|
||||
|
||||
/// Checks all services and returns their current status.
|
||||
pub async fn check_services(&mut self) -> Vec<ServiceStatus> {
|
||||
for service in &mut self.services {
|
||||
service.running = Self::check_service(&service.url).await;
|
||||
|
|
@ -321,7 +267,6 @@ impl ServiceMonitor {
|
|||
self.services.clone()
|
||||
}
|
||||
|
||||
/// Checks if a service is running at the given URL.
|
||||
pub async fn check_service(url: &str) -> bool {
|
||||
if !url.starts_with("http://") && !url.starts_with("https://") {
|
||||
return false;
|
||||
|
|
@ -344,19 +289,16 @@ impl ServiceMonitor {
|
|||
.is_ok_and(|response| response.status().is_success())
|
||||
}
|
||||
|
||||
/// Gets a service by name.
|
||||
#[must_use]
|
||||
pub fn get_service(&self, name: &str) -> Option<&ServiceStatus> {
|
||||
self.services.iter().find(|s| s.name == name)
|
||||
}
|
||||
|
||||
/// Returns whether all services are running.
|
||||
#[must_use]
|
||||
pub fn all_running(&self) -> bool {
|
||||
self.services.iter().all(|s| s.running)
|
||||
}
|
||||
|
||||
/// Returns whether any service is running.
|
||||
#[must_use]
|
||||
pub fn any_running(&self) -> bool {
|
||||
self.services.iter().any(|s| s.running)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,2 @@
|
|||
//! `BotApp` - Tauri desktop application for General Bots
|
||||
//!
|
||||
//! This crate wraps the web UI with native desktop features.
|
||||
|
||||
pub mod desktop;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue