mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-09 19:45:13 +02:00
Add error handling with NyxError and refactor console output formatting
- Introduced `NyxError` and `NyxResult` for unified error handling across modules. - Refactored `scan.rs`, `index.rs`, and `walk.rs` with improved error management and consistent formatting. - Replaced existing error handling in `database.rs` with `NyxResult`. - Improved database maintenance by integrating `vacuum` and `clear` methods into workflows. - Added `dashmap` for efficient parallel diagnostics result aggregation in `scan_with_index_parallel`. - Enhanced readability and formatting of console outputs in multiple modules.
This commit is contained in:
parent
75a20eaa2a
commit
0a66a0ae2d
14 changed files with 360 additions and 240 deletions
15
src/utils/ext.rs
Normal file
15
src/utils/ext.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
pub fn lowercase_ext(path: &std::path::Path) -> Option<&'static str> {
|
||||
path.extension()
|
||||
.and_then(|s| match s.to_str()? {
|
||||
"rs" | "RS" => Some("rs"),
|
||||
"c" => Some("c"),
|
||||
"cpp" | "c++" => Some("cpp"),
|
||||
"java" => Some("java"),
|
||||
"go" => Some("go"),
|
||||
"php" => Some("php"),
|
||||
"py" | "PY" => Some("py"),
|
||||
"ts" | "TSX" | "tsx" => Some("ts"),
|
||||
"js" => Some("js"),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod project;
|
||||
pub mod config;
|
||||
pub(crate) mod query_cache;
|
||||
pub(crate) mod ext;
|
||||
|
||||
// Re-export commonly used functions for convenience
|
||||
pub use project::{get_project_info};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,30 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use crate::errors::{NyxError, NyxResult};
|
||||
|
||||
/// Determine `<project-name, path/to/<project>.sqlite>`.
|
||||
pub fn get_project_info(
|
||||
project_path: &Path,
|
||||
config_dir: &Path,
|
||||
) -> Result<(String, PathBuf), Box<dyn std::error::Error>> {
|
||||
project_path: &Path,
|
||||
config_dir: &Path,
|
||||
) -> NyxResult<(String, PathBuf)> {
|
||||
|
||||
let project_name = project_path
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.ok_or("Unable to determine project name")?;
|
||||
|
||||
.and_then(|n| n.to_str())
|
||||
.ok_or_else(|| NyxError::Other("Unable to determine project name".into()))?;
|
||||
|
||||
let db_name = sanitize_project_name(project_name);
|
||||
let db_path = config_dir.join(format!("{}.sqlite", db_name));
|
||||
|
||||
Ok((project_name.to_string(), db_path))
|
||||
|
||||
Ok((project_name.to_owned(), db_path))
|
||||
}
|
||||
|
||||
pub fn sanitize_project_name(name: &str) -> String {
|
||||
pub fn sanitize_project_name(name: &str) -> String {
|
||||
name.to_lowercase()
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
' ' | '\t' | '\n' | '\r' => '_',
|
||||
c if c.is_alphanumeric() || c == '_' || c == '-' => c,
|
||||
_ => '_'
|
||||
.map(|c| match c {
|
||||
' ' | '\t' | '\n' | '\r' => '_',
|
||||
c if c.is_alphanumeric() || c == '_' || c == '-' => c,
|
||||
_ => '_',
|
||||
})
|
||||
.collect::<String>()
|
||||
.split('_')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::sync::RwLock;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use tree_sitter::{Language, Query};
|
||||
|
|
@ -8,30 +8,36 @@ use crate::patterns::{self, Pattern};
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct CompiledQuery {
|
||||
pub meta: Pattern,
|
||||
pub query: Arc<Query>,
|
||||
pub meta: Pattern,
|
||||
pub query: std::sync::Arc<Query>,
|
||||
}
|
||||
|
||||
static CACHE: Lazy<RwLock<HashMap<&'static str, Vec<CompiledQuery>>>> =
|
||||
static CACHE: Lazy<RwLock<HashMap<&'static str, std::sync::Arc<Vec<CompiledQuery>>>>> =
|
||||
Lazy::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
pub fn for_lang(lang: &'static str, ts_lang: Language) -> Vec<CompiledQuery> {
|
||||
// fast-path read
|
||||
/// Return **one shared Arc** to the per-language query set.
|
||||
/// Cloning the `Arc` is O(1) and the underlying Vec lives for the
|
||||
/// lifetime of the process.
|
||||
pub fn for_lang(lang: &'static str, ts_lang: Language) -> std::sync::Arc<Vec<CompiledQuery>> {
|
||||
// fast path
|
||||
if let Some(v) = CACHE.read().unwrap().get(lang) {
|
||||
return v.clone();
|
||||
}
|
||||
|
||||
// compile under write-lock exactly once
|
||||
let patterns = patterns::load(lang);
|
||||
let mut vec = Vec::with_capacity(patterns.len());
|
||||
|
||||
for p in patterns {
|
||||
// slow path — compile
|
||||
let patterns = patterns::load(lang);
|
||||
let compiled: Vec<_> = patterns.into_iter().filter_map(|p| {
|
||||
match Query::new(&ts_lang, p.query) {
|
||||
Ok(q) => vec.push(CompiledQuery { meta: p, query: Arc::new(q) }),
|
||||
Err(e) => tracing::warn!(lang, id = p.id, "query compile error: {e}"),
|
||||
Ok(q) => Some(CompiledQuery { meta: p, query: std::sync::Arc::new(q) }),
|
||||
Err(e)=> {
|
||||
tracing::warn!(lang, id = p.id, "query compile error: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}).collect();
|
||||
|
||||
CACHE.write().unwrap().insert(lang, vec.clone());
|
||||
vec
|
||||
let compiled = std::sync::Arc::new(compiled);
|
||||
|
||||
let mut w = CACHE.write().unwrap();
|
||||
w.entry(lang).or_insert_with(|| compiled.clone()).clone()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue