Refactor: Fix clippy warnings and introduce AppError
This commit is contained in:
1 parent
3add6c3d31
commit
4e1a633dbd
13 files changed
+129
-103
No files matched your search
@@ -19,9 +19,9 @@ pub fn spawn_watcher(state: Arc<MemoryState>) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(_clip) = tokio::task::spawn_blocking(|| Clipboard::new_attempts(3)).await.unwrap() {
|
||||
if let Ok(text) = get_clipboard::<String, _>(formats::Unicode) {
|
||||
if text != last_text && !text.trim().is_empty() {
|
||||
if let Ok(_clip) = tokio::task::spawn_blocking(|| Clipboard::new_attempts(3)).await.unwrap()
|
||||
&& let Ok(text) = get_clipboard::<String, _>(formats::Unicode)
|
||||
&& text != last_text && !text.trim().is_empty() {
|
||||
last_text = text.clone();
|
||||
|
||||
let note = StickyNote {
|
||||
@@ -40,8 +40,6 @@ pub fn spawn_watcher(state: Arc<MemoryState>) {
|
||||
// We use rebuild_index to index the new sticky note
|
||||
state.rebuild_index().await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
+17
-1
@@ -6,6 +6,8 @@ use axum::{
|
||||
use serde_json::json;
|
||||
use thiserror::Error;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, AppError>;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum AppError {
|
||||
#[error("Not Found: {0}")]
|
||||
@@ -19,6 +21,18 @@ pub enum AppError {
|
||||
|
||||
#[error("Bad Request: {0}")]
|
||||
BadRequest(String),
|
||||
|
||||
#[error("Serialization Error: {0}")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
|
||||
#[error("I/O Error: {0}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl From<AppError> for String {
|
||||
fn from(err: AppError) -> String {
|
||||
err.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
@@ -26,8 +40,10 @@ impl IntoResponse for AppError {
|
||||
let (status, error_message) = match &self {
|
||||
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
|
||||
AppError::Forbidden(msg) => (StatusCode::FORBIDDEN, msg.clone()),
|
||||
AppError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
|
||||
AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
|
||||
AppError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
|
||||
AppError::JsonError(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("JSON Error: {}", e)),
|
||||
AppError::IoError(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("I/O Error: {}", e)),
|
||||
};
|
||||
|
||||
let body = Json(json!({
|
||||
|
||||
@@ -55,13 +55,7 @@ impl McpTool for ReadFileSkeletonHandler {
|
||||
fn extract_skeleton(node: Node, code: &str, out: &mut String, depth: usize) {
|
||||
let kind = node.kind();
|
||||
|
||||
let is_structural = match kind {
|
||||
"use_declaration" | "import_statement" | "import_from_statement" => true,
|
||||
"struct_item" | "enum_item" | "trait_item" | "impl_item" => true,
|
||||
"function_item" | "function_declaration" | "function_definition" | "method_definition" => true,
|
||||
"interface_declaration" | "type_alias_declaration" | "class_declaration" | "class_definition" => true,
|
||||
_ => false,
|
||||
};
|
||||
let is_structural = matches!(kind, "use_declaration" | "import_statement" | "import_from_statement" | "struct_item" | "enum_item" | "trait_item" | "impl_item" | "function_item" | "function_declaration" | "function_definition" | "method_definition" | "interface_declaration" | "type_alias_declaration" | "class_declaration" | "class_definition");
|
||||
|
||||
if is_structural {
|
||||
let indent = " ".repeat(depth);
|
||||
@@ -84,7 +78,7 @@ impl McpTool for ReadFileSkeletonHandler {
|
||||
}
|
||||
|
||||
out.push_str(&indent);
|
||||
out.push_str(&signature.trim());
|
||||
out.push_str(signature.trim());
|
||||
out.push('\n');
|
||||
} else if node.is_named() {
|
||||
let mut cursor = node.walk();
|
||||
|
||||
@@ -27,11 +27,10 @@ impl McpTool for GetActiveWorktreeContextHandler {
|
||||
let repo = git2::Repository::discover(&cwd).map_err(|e| format!("Not in a git repository: {}", e))?;
|
||||
|
||||
let mut branch_name = String::new();
|
||||
if let Ok(head) = repo.head() {
|
||||
if let Some(name) = head.shorthand() {
|
||||
if let Ok(head) = repo.head()
|
||||
&& let Some(name) = head.shorthand() {
|
||||
branch_name = name.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
let mut opts = git2::DiffOptions::new();
|
||||
let mut diff = None;
|
||||
|
||||
@@ -409,7 +409,7 @@ impl McpTool for OmniSearchHandler {
|
||||
));
|
||||
}
|
||||
};
|
||||
println!("OMNI SEARCH MATCHES: {:?}", matches);
|
||||
// tracing::info!("OMNI SEARCH MATCHES: {:?}", matches);
|
||||
let q = req.query.clone();
|
||||
let query_emb = crate::embedding::generate_embedding_async(q.clone()).await.unwrap_or_default();
|
||||
|
||||
@@ -846,7 +846,7 @@ mod tests {
|
||||
.execute(json!({"query": "Omni"}), state.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
println!("OMNI RES: {}", omni_res);
|
||||
// tracing::info!("OMNI RES: {}", omni_res);
|
||||
assert!(
|
||||
omni_res.contains("omni-1"),
|
||||
"omni search should return results containing the task id"
|
||||
|
||||
@@ -32,25 +32,21 @@ impl McpTool for WriteClipboardHandler {
|
||||
let mut msgs = Vec::new();
|
||||
|
||||
// Handle clipboard_win formats (text, html, files)
|
||||
if tool_args.text.is_some() || tool_args.html.is_some() || tool_args.files.is_some() {
|
||||
if let Ok(_clip) = Clipboard::new_attempts(3) {
|
||||
if let Some(text) = &tool_args.text {
|
||||
if clipboard_win::set_clipboard_string(text).is_ok() {
|
||||
if (tool_args.text.is_some() || tool_args.html.is_some() || tool_args.files.is_some())
|
||||
&& let Ok(_clip) = Clipboard::new_attempts(3) {
|
||||
if let Some(text) = &tool_args.text
|
||||
&& clipboard_win::set_clipboard_string(text).is_ok() {
|
||||
msgs.push("Wrote text");
|
||||
}
|
||||
}
|
||||
if let Some(html) = &tool_args.html {
|
||||
if formats::Html::new().unwrap().write_clipboard(html).is_ok() {
|
||||
if let Some(html) = &tool_args.html
|
||||
&& formats::Html::new().unwrap().write_clipboard(html).is_ok() {
|
||||
msgs.push("Wrote HTML");
|
||||
}
|
||||
}
|
||||
if let Some(files) = &tool_args.files {
|
||||
if raw::set_file_list(files).is_ok() {
|
||||
if let Some(files) = &tool_args.files
|
||||
&& raw::set_file_list(files).is_ok() {
|
||||
msgs.push("Wrote FileList");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle arboard for image
|
||||
if let Some(image_path) = &tool_args.image_path {
|
||||
@@ -106,26 +102,23 @@ impl McpTool for ReadClipboardHandler {
|
||||
let mut out = serde_json::Map::new();
|
||||
|
||||
if let Ok(_clip) = Clipboard::new_attempts(3) {
|
||||
if let Ok(text) = get_clipboard::<String, _>(formats::Unicode) {
|
||||
if !text.trim().is_empty() {
|
||||
if let Ok(text) = get_clipboard::<String, _>(formats::Unicode)
|
||||
&& !text.trim().is_empty() {
|
||||
out.insert("text".into(), json!(text));
|
||||
}
|
||||
}
|
||||
if let Ok(html) = get_clipboard::<String, _>(formats::Html::new().unwrap()) {
|
||||
if !html.trim().is_empty() {
|
||||
if let Ok(html) = get_clipboard::<String, _>(formats::Html::new().unwrap())
|
||||
&& !html.trim().is_empty() {
|
||||
out.insert("html".into(), json!(html));
|
||||
}
|
||||
}
|
||||
if let Ok(files) = get_clipboard::<Vec<String>, _>(formats::FileList) {
|
||||
if !files.is_empty() {
|
||||
if let Ok(files) = get_clipboard::<Vec<String>, _>(formats::FileList)
|
||||
&& !files.is_empty() {
|
||||
out.insert("files".into(), json!(files));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(mut clipboard) = arboard::Clipboard::new() {
|
||||
if let Ok(image_data) = clipboard.get_image() {
|
||||
if let Some(img) = ImageBuffer::<image::Rgba<u8>, _>::from_raw(
|
||||
if let Ok(mut clipboard) = arboard::Clipboard::new()
|
||||
&& let Ok(image_data) = clipboard.get_image()
|
||||
&& let Some(img) = ImageBuffer::<image::Rgba<u8>, _>::from_raw(
|
||||
image_data.width as u32,
|
||||
image_data.height as u32,
|
||||
image_data.bytes.into_owned(),
|
||||
@@ -152,8 +145,6 @@ impl McpTool for ReadClipboardHandler {
|
||||
out.insert("image_path".into(), json!(file_path.to_string_lossy().to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Object(out))
|
||||
})
|
||||
|
||||
@@ -22,7 +22,7 @@ pub async fn start_background_indexer(state: Arc<MemoryState>) {
|
||||
for result in walker {
|
||||
match result {
|
||||
Ok(entry) => {
|
||||
if entry.file_type().map_or(false, |ft| ft.is_file()) {
|
||||
if entry.file_type().is_some_and(|ft| ft.is_file()) {
|
||||
let path = entry.path().to_path_buf();
|
||||
let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");
|
||||
if ["rs", "ts", "js", "jsx", "tsx", "py", "java", "c", "cpp", "go"].contains(&ext) {
|
||||
@@ -98,7 +98,7 @@ pub async fn start_background_indexer(state: Arc<MemoryState>) {
|
||||
});
|
||||
}
|
||||
|
||||
fn extract_chunks(node: Node, code: &str, chunks: &mut Vec<(String, String, String)>, ext: &str) {
|
||||
fn extract_chunks(node: Node, code: &str, chunks: &mut Vec<(String, String, String)>, _ext: &str) {
|
||||
let kind = node.kind();
|
||||
let is_structural = matches!(
|
||||
kind,
|
||||
@@ -128,7 +128,7 @@ fn extract_chunks(node: Node, code: &str, chunks: &mut Vec<(String, String, Stri
|
||||
} else {
|
||||
let mut cursor = node.walk();
|
||||
for child in node.named_children(&mut cursor) {
|
||||
extract_chunks(child, code, chunks, ext);
|
||||
extract_chunks(child, code, chunks, _ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,7 @@ impl MemoryIndex {
|
||||
}
|
||||
|
||||
pub fn add_task_sync(&self, t: &Task) {
|
||||
println!("add_task_sync called for task: {}", t.id);
|
||||
// println!("add_task_sync called for task: {}", t.id);
|
||||
if let Ok(writer) = self.writer.lock() {
|
||||
let _res = writer.add_document(doc!(
|
||||
self.id_field => t.id.as_str(),
|
||||
@@ -267,12 +267,12 @@ impl MemoryIndex {
|
||||
self.type_field => "task",
|
||||
self.namespace_field => "global"
|
||||
));
|
||||
println!("Writer add_document returned id/result");
|
||||
// println!("Writer add_document returned id/result");
|
||||
self.needs_commit
|
||||
.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
println!("Needs_commit set to true in add_task_sync");
|
||||
// println!("Needs_commit set to true in add_task_sync");
|
||||
} else {
|
||||
println!("Failed to acquire writer lock in add_task_sync");
|
||||
// println!("Failed to acquire writer lock in add_task_sync");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-7
@@ -1,6 +1,7 @@
|
||||
use crate::models::*;
|
||||
use crate::search::MemoryIndex;
|
||||
use crate::store::Store;
|
||||
use crate::vector_db::VectorDB;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
@@ -17,6 +18,7 @@ pub struct MemoryState {
|
||||
pub clipboard_watch_mode: tokio::sync::RwLock<bool>,
|
||||
pub graph: Store<KnowledgeGraph>,
|
||||
pub search_index: RwLock<MemoryIndex>,
|
||||
pub vector_db: tokio::sync::RwLock<Option<VectorDB>>,
|
||||
pub ledger: Store<Vec<CodeChange>>,
|
||||
pub sticky: Store<Vec<StickyNote>>,
|
||||
pub tasks: Store<Vec<Task>>,
|
||||
@@ -63,6 +65,7 @@ impl MemoryState {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}),
|
||||
vector_db: tokio::sync::RwLock::new(None),
|
||||
ledger: Store::new("audit_ledger", db.clone()),
|
||||
sticky: Store::new("sticky_notes", db.clone()),
|
||||
tasks: Store::new("tasks", db.clone()),
|
||||
@@ -144,7 +147,7 @@ impl MemoryState {
|
||||
let snippets = self.snippets.read_with(|s| s.clone());
|
||||
let adrs = self.adrs.read_with(|a| a.clone());
|
||||
|
||||
println!(
|
||||
tracing::info!(
|
||||
"rebuild_index: found {} entities, {} tasks",
|
||||
entities.len(),
|
||||
tasks.len()
|
||||
@@ -152,7 +155,7 @@ impl MemoryState {
|
||||
|
||||
let idx_clone = idx.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
println!("spawn_blocking started in rebuild_index");
|
||||
// tracing::info!("spawn_blocking started in rebuild_index");
|
||||
for e in entities {
|
||||
idx_clone.add_entity_sync(&e);
|
||||
}
|
||||
@@ -222,13 +225,13 @@ mod tests {
|
||||
let idx = arc_state.search_index.read().unwrap();
|
||||
// Force reload reader to ensure it sees the commit made by rebuild_index
|
||||
idx.reader.reload().unwrap();
|
||||
println!(
|
||||
"Index reader doc count: {}",
|
||||
idx.reader.searcher().num_docs()
|
||||
);
|
||||
// tracing::info!(
|
||||
// "Index reader doc count: {}",
|
||||
// idx.reader.searcher().num_docs()
|
||||
// );
|
||||
|
||||
let all_docs = idx.search("Test", None).expect("Search failed");
|
||||
println!("All docs for 'Test': {:?}", all_docs);
|
||||
// tracing::info!("All docs for 'Test': {:?}", all_docs);
|
||||
|
||||
// Verify the task added synchronously is actually searchable
|
||||
let results = idx.search("Test", None).expect("Search failed");
|
||||
|
||||
@@ -3,7 +3,7 @@ use qdrant_client::Qdrant;
|
||||
use std::sync::Arc;
|
||||
use std::error::Error;
|
||||
use uuid::Uuid;
|
||||
use tracing::{info, error};
|
||||
use tracing::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
Reference in new issue
Block a user