Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.

Commit f4e46f2

Browse files
committed
Improve Comment function with proper typed enum for location handling
- Replace serde_json::Value with ResolvedLocation enum using serde(untagged) - Cleaner type-safe handling of FileRange, SymbolDef, SymbolRef, SearchResults - Better error messages and compile-time safety - Maintains same functionality with improved code structure - Proper separation between input (Dialect program) and resolved types
1 parent a98980a commit f4e46f2

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

server/src/ide.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,20 @@ impl<U: IpcClient> DialectFunction<U> for GitDiff {
271271
/// - `{"comment": {"location": {"search": {"path": "src/", "regex": "fn main"}}, "icon": "warning", "content": ["Entry point"]}}`
272272
#[derive(Deserialize)]
273273
pub struct Comment {
274-
pub location: serde_json::Value, // Will be resolved to FileRange
274+
pub location: serde_json::Value, // Dialect program that resolves to a location
275275
pub icon: Option<String>,
276276
pub content: Vec<String>,
277277
}
278278

279+
#[derive(Deserialize)]
280+
#[serde(untagged)]
281+
pub enum ResolvedLocation {
282+
FileRange(FileRange),
283+
SymbolDef(SymbolDef),
284+
SymbolRef(SymbolRef),
285+
SearchResults(Vec<FileRange>),
286+
}
287+
279288
#[derive(Serialize)]
280289
pub struct ResolvedComment {
281290
pub location: FileRange,
@@ -292,30 +301,23 @@ impl<U: IpcClient> DialectFunction<U> for Comment {
292301
self,
293302
interpreter: &mut DialectInterpreter<U>,
294303
) -> anyhow::Result<Self::Output> {
295-
// Evaluate the location to get concrete location data
304+
// Evaluate the location Dialect program
296305
let location_result = interpreter.evaluate(self.location).await?;
297306

307+
// Deserialize to our typed enum for proper handling
308+
let resolved_location: ResolvedLocation = serde_json::from_value(location_result)?;
309+
298310
// Normalize different location types to FileRange
299-
let file_range = match location_result {
300-
serde_json::Value::Object(obj) => {
301-
// Check if it's a SymbolDef or SymbolRef with definedAt/referencedAt field
302-
if let Some(defined_at) = obj.get("definedAt") {
303-
serde_json::from_value(defined_at.clone())?
304-
} else if let Some(referenced_at) = obj.get("referencedAt") {
305-
serde_json::from_value(referenced_at.clone())?
306-
} else {
307-
// Assume it's already a FileRange
308-
serde_json::from_value(serde_json::Value::Object(obj))?
309-
}
310-
}
311-
// If it's an array, take the first element (e.g., from Search results)
312-
serde_json::Value::Array(mut arr) => {
313-
if arr.is_empty() {
314-
return Err(anyhow::anyhow!("Location resolved to empty array"));
311+
let file_range = match resolved_location {
312+
ResolvedLocation::FileRange(range) => range,
313+
ResolvedLocation::SymbolDef(def) => def.defined_at,
314+
ResolvedLocation::SymbolRef(ref_) => ref_.referenced_at,
315+
ResolvedLocation::SearchResults(mut results) => {
316+
if results.is_empty() {
317+
return Err(anyhow::anyhow!("Location resolved to empty search results"));
315318
}
316-
serde_json::from_value(arr.remove(0))?
319+
results.remove(0)
317320
}
318-
_ => return Err(anyhow::anyhow!("Invalid location type")),
319321
};
320322

321323
Ok(ResolvedComment {

0 commit comments

Comments
 (0)