Run cargo fmt across all crates
Some checks failed
CI / Format (push) Successful in 2s
CI / Clippy (push) Failing after 1m23s
CI / Security Audit (push) Has been skipped
CI / Tests (push) Has been skipped
CI / Clippy (pull_request) Failing after 1m18s
CI / Security Audit (pull_request) Has been skipped
CI / Tests (pull_request) Has been skipped
CI / Format (pull_request) Successful in 3s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-03-04 23:30:26 +01:00
parent 89c30a62dd
commit c9dc96ad73
23 changed files with 230 additions and 184 deletions

View File

@@ -103,8 +103,7 @@ pub async fn trigger_scan(
Extension(agent): AgentExt,
Path(id): Path<String>,
) -> Result<Json<serde_json::Value>, StatusCode> {
let oid =
mongodb::bson::oid::ObjectId::parse_str(&id).map_err(|_| StatusCode::BAD_REQUEST)?;
let oid = mongodb::bson::oid::ObjectId::parse_str(&id).map_err(|_| StatusCode::BAD_REQUEST)?;
let target = agent
.db
@@ -207,8 +206,7 @@ pub async fn get_finding(
Extension(agent): AgentExt,
Path(id): Path<String>,
) -> Result<Json<ApiResponse<DastFinding>>, StatusCode> {
let oid =
mongodb::bson::oid::ObjectId::parse_str(&id).map_err(|_| StatusCode::BAD_REQUEST)?;
let oid = mongodb::bson::oid::ObjectId::parse_str(&id).map_err(|_| StatusCode::BAD_REQUEST)?;
let finding = agent
.db

View File

@@ -235,12 +235,7 @@ pub async fn get_file_content(
// Cap at 10,000 lines
let truncated: String = content.lines().take(10_000).collect::<Vec<_>>().join("\n");
let language = params
.path
.rsplit('.')
.next()
.unwrap_or("")
.to_string();
let language = params.path.rsplit('.').next().unwrap_or("").to_string();
Ok(Json(ApiResponse {
data: FileContent {

View File

@@ -185,7 +185,9 @@ impl PipelineOrchestrator {
// Stage 4.5: Graph Building
tracing::info!("[{repo_id}] Stage 4.5: Graph Building");
self.update_phase(scan_run_id, "graph_building").await;
let graph_context = match self.build_code_graph(&repo_path, &repo_id, &all_findings).await
let graph_context = match self
.build_code_graph(&repo_path, &repo_id, &all_findings)
.await
{
Ok(ctx) => Some(ctx),
Err(e) => {
@@ -296,9 +298,10 @@ impl PipelineOrchestrator {
let graph_build_id = uuid::Uuid::new_v4().to_string();
let engine = compliance_graph::GraphEngine::new(50_000);
let (mut code_graph, build_run) = engine
.build_graph(repo_path, repo_id, &graph_build_id)
.map_err(|e| AgentError::Other(format!("Graph build error: {e}")))?;
let (mut code_graph, build_run) =
engine
.build_graph(repo_path, repo_id, &graph_build_id)
.map_err(|e| AgentError::Other(format!("Graph build error: {e}")))?;
// Apply community detection
compliance_graph::graph::community::apply_communities(&mut code_graph);
@@ -348,15 +351,11 @@ impl PipelineOrchestrator {
use futures_util::TryStreamExt;
let filter = mongodb::bson::doc! { "repo_id": repo_id };
let targets: Vec<compliance_core::models::DastTarget> = match self
.db
.dast_targets()
.find(filter)
.await
{
Ok(cursor) => cursor.try_collect().await.unwrap_or_default(),
Err(_) => return,
};
let targets: Vec<compliance_core::models::DastTarget> =
match self.db.dast_targets().find(filter).await {
Ok(cursor) => cursor.try_collect().await.unwrap_or_default(),
Err(_) => return,
};
if targets.is_empty() {
tracing::info!("[{repo_id}] No DAST targets configured, skipping");
@@ -379,10 +378,7 @@ impl PipelineOrchestrator {
tracing::error!("Failed to store DAST finding: {e}");
}
}
tracing::info!(
"DAST scan complete: {} findings",
findings.len()
);
tracing::info!("DAST scan complete: {} findings", findings.len());
}
Err(e) => {
tracing::error!("DAST scan failed: {e}");

View File

@@ -31,9 +31,15 @@ pub struct TrackedRepository {
pub last_scanned_commit: Option<String>,
#[serde(default, deserialize_with = "deserialize_findings_count")]
pub findings_count: u32,
#[serde(default = "chrono::Utc::now", deserialize_with = "deserialize_datetime")]
#[serde(
default = "chrono::Utc::now",
deserialize_with = "deserialize_datetime"
)]
pub created_at: DateTime<Utc>,
#[serde(default = "chrono::Utc::now", deserialize_with = "deserialize_datetime")]
#[serde(
default = "chrono::Utc::now",
deserialize_with = "deserialize_datetime"
)]
pub updated_at: DateTime<Utc>,
}
@@ -51,9 +57,7 @@ where
let bson = bson::Bson::deserialize(deserializer)?;
match bson {
bson::Bson::DateTime(dt) => Ok(dt.into()),
bson::Bson::String(s) => s
.parse::<DateTime<Utc>>()
.map_err(serde::de::Error::custom),
bson::Bson::String(s) => s.parse::<DateTime<Utc>>().map_err(serde::de::Error::custom),
other => Err(serde::de::Error::custom(format!(
"expected DateTime or string, got: {other:?}"
))),

View File

@@ -47,17 +47,19 @@ fn insert_path(
let name = parts[0].to_string();
let is_leaf = parts.len() == 1;
let entry = children.entry(name.clone()).or_insert_with(|| FileTreeNode {
name: name.clone(),
path: if is_leaf {
full_path.to_string()
} else {
String::new()
},
is_dir: !is_leaf,
node_count: 0,
children: Vec::new(),
});
let entry = children
.entry(name.clone())
.or_insert_with(|| FileTreeNode {
name: name.clone(),
path: if is_leaf {
full_path.to_string()
} else {
String::new()
},
is_dir: !is_leaf,
node_count: 0,
children: Vec::new(),
});
if is_leaf {
entry.node_count = node_count;

View File

@@ -39,11 +39,11 @@ impl Toasts {
#[cfg(feature = "web")]
{
let mut items = self.items;
spawn(async move {
gloo_timers::future::TimeoutFuture::new(4_000).await;
items.write().retain(|t| t.id != id);
});
let mut items = self.items;
spawn(async move {
gloo_timers::future::TimeoutFuture::new(4_000).await;
items.write().retain(|t| t.id != id);
});
}
}

View File

@@ -87,10 +87,7 @@ pub async fn fetch_dast_finding_detail(
}
#[server]
pub async fn add_dast_target(
name: String,
base_url: String,
) -> Result<(), ServerFnError> {
pub async fn add_dast_target(name: String, base_url: String) -> Result<(), ServerFnError> {
let state: super::server_state::ServerState =
dioxus_fullstack::FullstackContext::extract().await?;
let url = format!("{}/api/v1/dast/targets", state.agent_api_url);

View File

@@ -121,10 +121,7 @@ pub async fn fetch_file_content(
}
#[server]
pub async fn search_nodes(
repo_id: String,
query: String,
) -> Result<SearchResponse, ServerFnError> {
pub async fn search_nodes(repo_id: String, query: String) -> Result<SearchResponse, ServerFnError> {
let state: super::server_state::ServerState =
dioxus_fullstack::FullstackContext::extract().await?;
let url = format!(

View File

@@ -14,7 +14,9 @@ pub fn FindingsPage() -> Element {
let mut repo_filter = use_signal(String::new);
let repos = use_resource(|| async {
crate::infrastructure::repositories::fetch_repositories(1).await.ok()
crate::infrastructure::repositories::fetch_repositories(1)
.await
.ok()
});
let findings = use_resource(move || {

View File

@@ -234,10 +234,7 @@ impl ApiFuzzerAgent {
.ok()?;
let headers = response.headers();
let acao = headers
.get("access-control-allow-origin")?
.to_str()
.ok()?;
let acao = headers.get("access-control-allow-origin")?.to_str().ok()?;
if acao == "*" || acao == "https://evil.com" {
let acac = headers
@@ -265,12 +262,9 @@ impl ApiFuzzerAgent {
request_body: None,
response_status: response.status().as_u16(),
response_headers: Some(
[(
"Access-Control-Allow-Origin".to_string(),
acao.to_string(),
)]
.into_iter()
.collect(),
[("Access-Control-Allow-Origin".to_string(), acao.to_string())]
.into_iter()
.collect(),
),
response_snippet: None,
screenshot_path: None,

View File

@@ -132,7 +132,10 @@ impl DastAgent for AuthBypassAgent {
String::new(),
target_id.clone(),
DastVulnType::AuthBypass,
format!("HTTP method tampering: {} accepted on {}", method, endpoint.url),
format!(
"HTTP method tampering: {} accepted on {}",
method, endpoint.url
),
format!(
"Endpoint {} accepts {} requests which may bypass access controls.",
endpoint.url, method

View File

@@ -20,10 +20,7 @@ impl SsrfAgent {
("http://[::1]", "localhost IPv6"),
("http://0.0.0.0", "zero address"),
("http://169.254.169.254/latest/meta-data/", "AWS metadata"),
(
"http://metadata.google.internal/",
"GCP metadata",
),
("http://metadata.google.internal/", "GCP metadata"),
("http://127.0.0.1:22", "SSH port probe"),
("http://127.0.0.1:3306", "MySQL port probe"),
("http://localhost/admin", "localhost admin"),
@@ -91,10 +88,7 @@ impl DastAgent for SsrfAgent {
.post(&endpoint.url)
.form(&[(param.name.as_str(), payload)])
} else {
let test_url = format!(
"{}?{}={}",
endpoint.url, param.name, payload
);
let test_url = format!("{}?{}={}", endpoint.url, param.name, payload);
self.http.get(&test_url)
};
@@ -133,10 +127,7 @@ impl DastAgent for SsrfAgent {
String::new(),
target_id.clone(),
DastVulnType::Ssrf,
format!(
"SSRF ({technique}) via parameter '{}'",
param.name
),
format!("SSRF ({technique}) via parameter '{}'", param.name),
format!(
"Server-side request forgery detected in parameter '{}' at {}. \
The application made a request to an internal resource ({}).",

View File

@@ -17,26 +17,11 @@ impl XssAgent {
fn payloads(&self) -> Vec<(&str, &str)> {
vec![
("<script>alert(1)</script>", "basic script injection"),
(
"<img src=x onerror=alert(1)>",
"event handler injection",
),
(
"<svg/onload=alert(1)>",
"svg event handler",
),
(
"javascript:alert(1)",
"javascript protocol",
),
(
"'\"><script>alert(1)</script>",
"attribute breakout",
),
(
"<body onload=alert(1)>",
"body event handler",
),
("<img src=x onerror=alert(1)>", "event handler injection"),
("<svg/onload=alert(1)>", "svg event handler"),
("javascript:alert(1)", "javascript protocol"),
("'\"><script>alert(1)</script>", "attribute breakout"),
("<body onload=alert(1)>", "body event handler"),
]
}
}
@@ -65,10 +50,7 @@ impl DastAgent for XssAgent {
for param in &endpoint.parameters {
for (payload, technique) in self.payloads() {
let test_url = if endpoint.method == "GET" {
format!(
"{}?{}={}",
endpoint.url, param.name, payload
)
format!("{}?{}={}", endpoint.url, param.name, payload)
} else {
endpoint.url.clone()
};

View File

@@ -28,8 +28,8 @@ impl WebCrawler {
base_url: &str,
excluded_paths: &[String],
) -> Result<Vec<DiscoveredEndpoint>, CoreError> {
let base = Url::parse(base_url)
.map_err(|e| CoreError::Dast(format!("Invalid base URL: {e}")))?;
let base =
Url::parse(base_url).map_err(|e| CoreError::Dast(format!("Invalid base URL: {e}")))?;
let mut visited: HashSet<String> = HashSet::new();
let mut endpoints: Vec<DiscoveredEndpoint> = Vec::new();
@@ -95,12 +95,13 @@ impl WebCrawler {
let document = Html::parse_document(&body);
// Extract links
let link_selector =
Selector::parse("a[href]").unwrap_or_else(|_| Selector::parse("a").expect("valid selector"));
let link_selector = Selector::parse("a[href]")
.unwrap_or_else(|_| Selector::parse("a").expect("valid selector"));
for element in document.select(&link_selector) {
if let Some(href) = element.value().attr("href") {
if let Some(absolute_url) = self.resolve_url(&base, &url, href) {
if self.is_same_origin(&base, &absolute_url) && !visited.contains(&absolute_url)
if self.is_same_origin(&base, &absolute_url)
&& !visited.contains(&absolute_url)
{
queue.push((absolute_url, depth + 1));
}
@@ -116,11 +117,7 @@ impl WebCrawler {
for form in document.select(&form_selector) {
let action = form.value().attr("action").unwrap_or("");
let method = form
.value()
.attr("method")
.unwrap_or("GET")
.to_uppercase();
let method = form.value().attr("method").unwrap_or("GET").to_uppercase();
let form_url = self
.resolve_url(&base, &url, action)
@@ -128,20 +125,12 @@ impl WebCrawler {
let mut params = Vec::new();
for input in form.select(&input_selector) {
let name = input
.value()
.attr("name")
.unwrap_or("")
.to_string();
let name = input.value().attr("name").unwrap_or("").to_string();
if name.is_empty() {
continue;
}
let input_type = input
.value()
.attr("type")
.unwrap_or("text")
.to_string();
let input_type = input.value().attr("type").unwrap_or("text").to_string();
let location = if method == "GET" {
"query".to_string()

View File

@@ -149,11 +149,8 @@ impl DastOrchestrator {
let t2 = target.clone();
let c2 = context.clone();
let h2 = http.clone();
let xss_handle = tokio::spawn(async move {
crate::agents::xss::XssAgent::new(h2)
.run(&t2, &c2)
.await
});
let xss_handle =
tokio::spawn(async move { crate::agents::xss::XssAgent::new(h2).run(&t2, &c2).await });
let t3 = target.clone();
let c3 = context.clone();
@@ -167,11 +164,10 @@ impl DastOrchestrator {
let t4 = target.clone();
let c4 = context.clone();
let h4 = http.clone();
let ssrf_handle = tokio::spawn(async move {
crate::agents::ssrf::SsrfAgent::new(h4)
.run(&t4, &c4)
.await
});
let ssrf_handle =
tokio::spawn(
async move { crate::agents::ssrf::SsrfAgent::new(h4).run(&t4, &c4).await },
);
let t5 = target.clone();
let c5 = context.clone();
@@ -182,8 +178,13 @@ impl DastOrchestrator {
.await
});
let handles: Vec<tokio::task::JoinHandle<Result<Vec<DastFinding>, CoreError>>> =
vec![sqli_handle, xss_handle, auth_handle, ssrf_handle, api_handle];
let handles: Vec<tokio::task::JoinHandle<Result<Vec<DastFinding>, CoreError>>> = vec![
sqli_handle,
xss_handle,
auth_handle,
ssrf_handle,
api_handle,
];
let mut all_findings = Vec::new();
for handle in handles {

View File

@@ -81,10 +81,9 @@ impl ReconAgent {
];
for header in &missing_security {
if !headers.contains_key(*header) {
result.interesting_headers.insert(
format!("missing:{header}"),
"Not present".to_string(),
);
result
.interesting_headers
.insert(format!("missing:{header}"), "Not present".to_string());
}
}

View File

@@ -26,8 +26,11 @@ impl<'a> ImpactAnalyzer<'a> {
file_path: &str,
line_number: Option<u32>,
) -> ImpactAnalysis {
let mut analysis =
ImpactAnalysis::new(repo_id.to_string(), finding_id.to_string(), graph_build_id.to_string());
let mut analysis = ImpactAnalysis::new(
repo_id.to_string(),
finding_id.to_string(),
graph_build_id.to_string(),
);
// Find the node containing the finding
let target_node = self.find_node_at_location(file_path, line_number);
@@ -97,7 +100,11 @@ impl<'a> ImpactAnalyzer<'a> {
}
/// Find the graph node at a given file/line location
fn find_node_at_location(&self, file_path: &str, line_number: Option<u32>) -> Option<NodeIndex> {
fn find_node_at_location(
&self,
file_path: &str,
line_number: Option<u32>,
) -> Option<NodeIndex> {
let mut best: Option<(NodeIndex, u32)> = None; // (index, line_span)
for node in &self.code_graph.nodes {
@@ -166,12 +173,7 @@ impl<'a> ImpactAnalyzer<'a> {
}
/// Find a path from source to target (BFS, limited depth)
fn find_path(
&self,
from: NodeIndex,
to: NodeIndex,
max_depth: usize,
) -> Option<Vec<String>> {
fn find_path(&self, from: NodeIndex, to: NodeIndex, max_depth: usize) -> Option<Vec<String>> {
let mut visited = HashSet::new();
let mut queue: VecDeque<(NodeIndex, Vec<NodeIndex>)> = VecDeque::new();
queue.push_back((from, vec![from]));
@@ -209,7 +211,10 @@ impl<'a> ImpactAnalyzer<'a> {
None
}
fn get_node_by_index(&self, idx: NodeIndex) -> Option<&compliance_core::models::graph::CodeNode> {
fn get_node_by_index(
&self,
idx: NodeIndex,
) -> Option<&compliance_core::models::graph::CodeNode> {
let target_gi = idx.index() as u32;
self.code_graph
.nodes

View File

@@ -211,8 +211,6 @@ impl GraphStore {
repo_id: &str,
graph_build_id: &str,
) -> Result<Vec<CommunityInfo>, CoreError> {
let filter = doc! {
"repo_id": repo_id,
"graph_build_id": graph_build_id,

View File

@@ -51,7 +51,13 @@ impl JavaScriptParser {
if let Some(body) = node.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified, output,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}
}
@@ -97,7 +103,12 @@ impl JavaScriptParser {
if let Some(body) = node.child_by_field_name("body") {
self.walk_children(
body, source, file_path, repo_id, graph_build_id, Some(&qualified),
body,
source,
file_path,
repo_id,
graph_build_id,
Some(&qualified),
output,
);
}
@@ -130,7 +141,13 @@ impl JavaScriptParser {
if let Some(body) = node.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified, output,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}
}
@@ -138,7 +155,13 @@ impl JavaScriptParser {
// Arrow functions assigned to variables: const foo = () => {}
"lexical_declaration" | "variable_declaration" => {
self.extract_arrow_functions(
node, source, file_path, repo_id, graph_build_id, parent_qualified, output,
node,
source,
file_path,
repo_id,
graph_build_id,
parent_qualified,
output,
);
}
"import_statement" => {
@@ -183,7 +206,13 @@ impl JavaScriptParser {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
self.walk_tree(
child, source, file_path, repo_id, graph_build_id, parent_qualified, output,
child,
source,
file_path,
repo_id,
graph_build_id,
parent_qualified,
output,
);
}
}
@@ -217,7 +246,13 @@ impl JavaScriptParser {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
self.extract_calls(
child, source, file_path, repo_id, graph_build_id, caller_qualified, output,
child,
source,
file_path,
repo_id,
graph_build_id,
caller_qualified,
output,
);
}
}
@@ -263,7 +298,12 @@ impl JavaScriptParser {
if let Some(body) = value_n.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}

View File

@@ -57,10 +57,7 @@ impl ParserRegistry {
repo_id: &str,
graph_build_id: &str,
) -> Result<Option<ParseOutput>, CoreError> {
let ext = file_path
.extension()
.and_then(|e| e.to_str())
.unwrap_or("");
let ext = file_path.extension().and_then(|e| e.to_str()).unwrap_or("");
let parser_idx = match self.extension_map.get(ext) {
Some(idx) => *idx,
@@ -89,7 +86,15 @@ impl ParserRegistry {
let mut combined = ParseOutput::default();
let mut node_count: u32 = 0;
self.walk_directory(dir, dir, repo_id, graph_build_id, max_nodes, &mut node_count, &mut combined)?;
self.walk_directory(
dir,
dir,
repo_id,
graph_build_id,
max_nodes,
&mut node_count,
&mut combined,
)?;
info!(
nodes = combined.nodes.len(),
@@ -162,8 +167,7 @@ impl ParserRegistry {
Err(_) => continue, // Skip binary/unreadable files
};
if let Some(output) = self.parse_file(rel_path, &source, repo_id, graph_build_id)?
{
if let Some(output) = self.parse_file(rel_path, &source, repo_id, graph_build_id)? {
*node_count += output.nodes.len() as u32;
combined.nodes.extend(output.nodes);
combined.edges.extend(output.edges);

View File

@@ -196,9 +196,7 @@ impl RustParser {
id: None,
repo_id: repo_id.to_string(),
graph_build_id: graph_build_id.to_string(),
source: parent_qualified
.unwrap_or(file_path)
.to_string(),
source: parent_qualified.unwrap_or(file_path).to_string(),
target: path,
kind: CodeEdgeKind::Imports,
file_path: file_path.to_string(),
@@ -354,10 +352,7 @@ impl RustParser {
fn extract_use_path(&self, use_text: &str) -> Option<String> {
// "use foo::bar::baz;" -> "foo::bar::baz"
let trimmed = use_text
.strip_prefix("use ")?
.trim_end_matches(';')
.trim();
let trimmed = use_text.strip_prefix("use ")?.trim_end_matches(';').trim();
Some(trimmed.to_string())
}
}

View File

@@ -49,7 +49,13 @@ impl TypeScriptParser {
if let Some(body) = node.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified, output,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}
}
@@ -80,12 +86,23 @@ impl TypeScriptParser {
// Heritage clause (extends/implements)
self.extract_heritage(
&node, source, file_path, repo_id, graph_build_id, &qualified, output,
&node,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
if let Some(body) = node.child_by_field_name("body") {
self.walk_children(
body, source, file_path, repo_id, graph_build_id, Some(&qualified),
body,
source,
file_path,
repo_id,
graph_build_id,
Some(&qualified),
output,
);
}
@@ -143,14 +160,26 @@ impl TypeScriptParser {
if let Some(body) = node.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified, output,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}
}
}
"lexical_declaration" | "variable_declaration" => {
self.extract_arrow_functions(
node, source, file_path, repo_id, graph_build_id, parent_qualified, output,
node,
source,
file_path,
repo_id,
graph_build_id,
parent_qualified,
output,
);
}
"import_statement" => {
@@ -172,7 +201,13 @@ impl TypeScriptParser {
}
self.walk_children(
node, source, file_path, repo_id, graph_build_id, parent_qualified, output,
node,
source,
file_path,
repo_id,
graph_build_id,
parent_qualified,
output,
);
}
@@ -189,7 +224,13 @@ impl TypeScriptParser {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
self.walk_tree(
child, source, file_path, repo_id, graph_build_id, parent_qualified, output,
child,
source,
file_path,
repo_id,
graph_build_id,
parent_qualified,
output,
);
}
}
@@ -223,7 +264,13 @@ impl TypeScriptParser {
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
self.extract_calls(
child, source, file_path, repo_id, graph_build_id, caller_qualified, output,
child,
source,
file_path,
repo_id,
graph_build_id,
caller_qualified,
output,
);
}
}
@@ -269,7 +316,12 @@ impl TypeScriptParser {
if let Some(body) = value_n.child_by_field_name("body") {
self.extract_calls(
body, source, file_path, repo_id, graph_build_id, &qualified,
body,
source,
file_path,
repo_id,
graph_build_id,
&qualified,
output,
);
}

View File

@@ -89,8 +89,10 @@ impl SymbolIndex {
.map_err(|e| CoreError::Graph(format!("Failed to create reader: {e}")))?;
let searcher = reader.searcher();
let query_parser =
QueryParser::for_index(&self.index, vec![self.name_field, self.qualified_name_field]);
let query_parser = QueryParser::for_index(
&self.index,
vec![self.name_field, self.qualified_name_field],
);
let query = query_parser
.parse_query(query_str)