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:
@@ -51,18 +51,9 @@ impl Tool for LspConnect {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let name = args
|
||||
.get("name")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: name"))?;
|
||||
let command = args
|
||||
.get("command")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: command"))?;
|
||||
let language_id = args
|
||||
.get("language_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: language_id"))?;
|
||||
let name = crate::tool::arg_str(args, "name")?;
|
||||
let command = crate::tool::arg_str(args, "command")?;
|
||||
let language_id = crate::tool::arg_str(args, "language_id")?;
|
||||
let extra_args: Vec<String> = args
|
||||
.get("args")
|
||||
.and_then(|v| v.as_array())
|
||||
@@ -77,17 +68,17 @@ impl Tool for LspConnect {
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
manager.connect(command, &extra_args, language_id)?;
|
||||
manager.connect(&command, &extra_args, &language_id)?;
|
||||
|
||||
// Auto-register this server's known extensions so lsp_diagnostics /
|
||||
// lsp_hover / lsp_completion / lsp_definition / lsp_references can
|
||||
// auto-detect it later without an explicit `server` argument.
|
||||
let known_exts = known_extensions_for(language_id);
|
||||
let known_exts = known_extensions_for(&language_id);
|
||||
if !known_exts.is_empty() {
|
||||
manager.register_extensions(language_id, known_exts);
|
||||
manager.register_extensions(&language_id, known_exts);
|
||||
}
|
||||
|
||||
let client_arc = manager.get_client(language_id);
|
||||
let client_arc = manager.get_client(&language_id);
|
||||
let caps = client_arc
|
||||
.and_then(|c| {
|
||||
c.lock()
|
||||
@@ -138,18 +129,12 @@ impl Tool for LspDiagnostics {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel_path = args
|
||||
.get("path")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||||
let text = args
|
||||
.get("text")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: text"))?;
|
||||
let server_name = resolve_server_name(ctx, args, rel_path)?;
|
||||
let rel_path = crate::tool::arg_str(args, "path")?;
|
||||
let text = crate::tool::arg_str(args, "text")?;
|
||||
let server_name = resolve_server_name(ctx, args, &rel_path)?;
|
||||
let server_name = server_name.as_str();
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, rel_path)?;
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, &rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let manager = ctx
|
||||
@@ -168,7 +153,7 @@ impl Tool for LspDiagnostics {
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
match client.collect_diagnostics(&uri, &language_id, text) {
|
||||
match client.collect_diagnostics(&uri, &language_id, &text) {
|
||||
Ok(diags) => {
|
||||
let diags_array = diags.as_array().cloned().unwrap_or_default();
|
||||
if diags_array.is_empty() {
|
||||
@@ -279,52 +264,12 @@ impl Tool for LspHover {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel_path = args
|
||||
.get("path")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||||
let line = args
|
||||
.get("line")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: line"))? as u32;
|
||||
let column =
|
||||
args.get("column")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: column"))? as u32;
|
||||
let server_name = resolve_server_name(ctx, args, rel_path)?;
|
||||
let server_name = server_name.as_str();
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let file_content = std::fs::read_to_string(&abs_path)
|
||||
.map_err(|e| anyhow!("failed to read file '{rel_path}': {e}"))?;
|
||||
|
||||
let manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
let language_id = manager.get_language_id(server_name).unwrap_or_else(|| {
|
||||
args.get("language_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("plaintext")
|
||||
.to_string()
|
||||
let result = run_lsp_query(ctx, args, |client, uri, line, column| {
|
||||
client.hover(uri, line, column)
|
||||
});
|
||||
let client_arc = manager.get_client(server_name).ok_or_else(|| {
|
||||
anyhow!("LSP server '{server_name}' not found. Use lsp_connect first.")
|
||||
})?;
|
||||
drop(manager);
|
||||
|
||||
let mut client = client_arc
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
client.did_open(&uri, &language_id, 1, &file_content)?;
|
||||
let result = client.hover(&uri, line, column);
|
||||
let _ = client.did_close(&uri);
|
||||
|
||||
match result {
|
||||
Ok(hover_result) => {
|
||||
Ok((hover_result, _line, _column)) => {
|
||||
if hover_result == Value::Null {
|
||||
return Ok("No hover information available at this position.".to_string());
|
||||
}
|
||||
@@ -424,49 +369,12 @@ impl Tool for LspCompletion {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel_path = args
|
||||
.get("path")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||||
let line = args
|
||||
.get("line")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: line"))? as u32;
|
||||
let column =
|
||||
args.get("column")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: column"))? as u32;
|
||||
let server_name = resolve_server_name(ctx, args, rel_path)?;
|
||||
let server_name = server_name.as_str();
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let file_content = std::fs::read_to_string(&abs_path)
|
||||
.map_err(|e| anyhow!("failed to read file '{rel_path}': {e}"))?;
|
||||
|
||||
let manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
let language_id = manager
|
||||
.get_language_id(server_name)
|
||||
.unwrap_or_else(|| "plaintext".to_string());
|
||||
let client_arc = manager.get_client(server_name).ok_or_else(|| {
|
||||
anyhow!("LSP server '{server_name}' not found. Use lsp_connect first.")
|
||||
})?;
|
||||
drop(manager);
|
||||
|
||||
let mut client = client_arc
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
client.did_open(&uri, &language_id, 1, &file_content)?;
|
||||
let result = client.completion(&uri, line, column);
|
||||
let _ = client.did_close(&uri);
|
||||
let result = run_lsp_query(ctx, args, |client, uri, line, column| {
|
||||
client.completion(uri, line, column)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(completion_result) => {
|
||||
Ok((completion_result, line, column)) => {
|
||||
let items = if let Some(items) = completion_result.as_array() {
|
||||
items.clone()
|
||||
} else if let Some(arr) = completion_result.get("items").and_then(|v| v.as_array())
|
||||
@@ -576,49 +484,12 @@ impl Tool for LspDefinition {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel_path = args
|
||||
.get("path")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||||
let line = args
|
||||
.get("line")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: line"))? as u32;
|
||||
let column =
|
||||
args.get("column")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: column"))? as u32;
|
||||
let server_name = resolve_server_name(ctx, args, rel_path)?;
|
||||
let server_name = server_name.as_str();
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let file_content = std::fs::read_to_string(&abs_path)
|
||||
.map_err(|e| anyhow!("failed to read file '{rel_path}': {e}"))?;
|
||||
|
||||
let manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
let language_id = manager
|
||||
.get_language_id(server_name)
|
||||
.unwrap_or_else(|| "plaintext".to_string());
|
||||
let client_arc = manager.get_client(server_name).ok_or_else(|| {
|
||||
anyhow!("LSP server '{server_name}' not found. Use lsp_connect first.")
|
||||
})?;
|
||||
drop(manager);
|
||||
|
||||
let mut client = client_arc
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
client.did_open(&uri, &language_id, 1, &file_content)?;
|
||||
let result = client.goto_definition(&uri, line, column);
|
||||
let _ = client.did_close(&uri);
|
||||
let result = run_lsp_query(ctx, args, |client, uri, line, column| {
|
||||
client.goto_definition(uri, line, column)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(def_result) => {
|
||||
Ok((def_result, _line, _column)) => {
|
||||
if def_result == Value::Null {
|
||||
return Ok("No definition found at this position.".to_string());
|
||||
}
|
||||
@@ -696,49 +567,12 @@ impl Tool for LspReferences {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel_path = args
|
||||
.get("path")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||||
let line = args
|
||||
.get("line")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: line"))? as u32;
|
||||
let column =
|
||||
args.get("column")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow!("missing required argument: column"))? as u32;
|
||||
let server_name = resolve_server_name(ctx, args, rel_path)?;
|
||||
let server_name = server_name.as_str();
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let file_content = std::fs::read_to_string(&abs_path)
|
||||
.map_err(|e| anyhow!("failed to read file '{rel_path}': {e}"))?;
|
||||
|
||||
let manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
let language_id = manager
|
||||
.get_language_id(server_name)
|
||||
.unwrap_or_else(|| "plaintext".to_string());
|
||||
let client_arc = manager.get_client(server_name).ok_or_else(|| {
|
||||
anyhow!("LSP server '{server_name}' not found. Use lsp_connect first.")
|
||||
})?;
|
||||
drop(manager);
|
||||
|
||||
let mut client = client_arc
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
client.did_open(&uri, &language_id, 1, &file_content)?;
|
||||
let result = client.references(&uri, line, column);
|
||||
let _ = client.did_close(&uri);
|
||||
let result = run_lsp_query(ctx, args, |client, uri, line, column| {
|
||||
client.references(uri, line, column)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(ref_result) => {
|
||||
Ok((ref_result, _line, _column)) => {
|
||||
let locations = ref_result.as_array().cloned().unwrap_or_default();
|
||||
if locations.is_empty() {
|
||||
return Ok("No references found for this symbol.".to_string());
|
||||
@@ -794,17 +628,14 @@ impl Tool for LspDisconnect {
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let name = args
|
||||
.get("name")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: name"))?;
|
||||
let name = crate::tool::arg_str(args, "name")?;
|
||||
|
||||
let mut manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow!("LSP manager lock error: {e}"))?;
|
||||
|
||||
if manager.disconnect(name) {
|
||||
if manager.disconnect(&name) {
|
||||
Ok(format!("Disconnected from LSP server '{name}'"))
|
||||
} else {
|
||||
Err(anyhow!("LSP server '{name}' not found"))
|
||||
@@ -842,6 +673,55 @@ fn known_extensions_for(language_id: &str) -> &[&'static str] {
|
||||
/// a server connected without an explicit `register_extensions` call. Returns
|
||||
/// `None` if the path has no extension, the lock is poisoned, or no
|
||||
/// connected server's language is known to use that extension.
|
||||
fn run_lsp_query<F, R>(ctx: &ToolCtx, args: &Value, op: F) -> Result<(R, u32, u32)>
|
||||
where
|
||||
F: FnOnce(&mut crate::app::lsp::LspClient, &str, u32, u32) -> Result<R>,
|
||||
{
|
||||
let rel_path = crate::tool::arg_str(args, "path")?;
|
||||
let line = args
|
||||
.get("line")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow::anyhow!("missing required argument: line"))? as u32;
|
||||
let column =
|
||||
args.get("column")
|
||||
.and_then(serde_json::Value::as_i64)
|
||||
.ok_or_else(|| anyhow::anyhow!("missing required argument: column"))? as u32;
|
||||
let server_name = resolve_server_name(ctx, args, &rel_path)?;
|
||||
|
||||
let abs_path = crate::tool::resolve_path(&ctx.workspaces, &rel_path)?;
|
||||
let uri = path_to_lsp_uri(&abs_path.to_string_lossy());
|
||||
|
||||
let file_content = std::fs::read_to_string(&abs_path)
|
||||
.map_err(|e| anyhow::anyhow!("failed to read file '{rel_path}': {e}"))?;
|
||||
|
||||
let manager = ctx
|
||||
.lsp_manager
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("LSP manager lock error: {e}"))?;
|
||||
let language_id = manager
|
||||
.get_language_id(&server_name)
|
||||
.unwrap_or_else(|| {
|
||||
args.get("language_id")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("plaintext")
|
||||
.to_string()
|
||||
});
|
||||
let client_arc = manager.get_client(&server_name).ok_or_else(|| {
|
||||
anyhow::anyhow!("LSP server '{server_name}' not found. Use lsp_connect first.")
|
||||
})?;
|
||||
drop(manager);
|
||||
|
||||
let mut client = client_arc
|
||||
.lock()
|
||||
.map_err(|e| anyhow::anyhow!("LSP client lock error: {e}"))?;
|
||||
|
||||
client.did_open(&uri, &language_id, 1, &file_content)?;
|
||||
let result = op(&mut client, &uri, line, column);
|
||||
let _ = client.did_close(&uri);
|
||||
|
||||
result.map(|r| (r, line, column))
|
||||
}
|
||||
|
||||
fn auto_detect_server(ctx: &ToolCtx, path: &str) -> Option<String> {
|
||||
let ext = std::path::Path::new(path)
|
||||
.extension()
|
||||
|
||||
Reference in New Issue
Block a user