refactor: improve readability of streaming and file ops code
Agent: carmack databricks.rs: - Extract ToolCallAccumulator struct to replace opaque (String, String, String) tuple - Add decode_utf8_streaming() helper for cleaner UTF-8 handling - Add is_incomplete_json_error() helper for JSON parse error detection - Add make_final_chunk() helper to reduce duplication - Add finalize_tool_calls() to convert accumulators to final format - Refactor parse_streaming_response from ~270 lines to ~100 lines - Reduce nesting depth from 8+ levels to 4 levels - Use early returns and let-else for cleaner control flow file_ops.rs: - Replace repetitive if-let chains with declarative PATH_CONTENT_KEYS table - Use match expression instead of nested if-else - Reduce extract_path_and_content from 44 lines to 20 lines All tests pass. Behavior unchanged.
This commit is contained in:
@@ -345,48 +345,35 @@ pub async fn execute_str_replace<W: UiWriter>(
|
||||
|
||||
// Helper functions
|
||||
|
||||
/// Known argument key pairs for path and content.
|
||||
const PATH_CONTENT_KEYS: &[(&str, &str)] = &[
|
||||
("file_path", "content"), // Standard format
|
||||
("path", "content"), // Anthropic-style
|
||||
("filename", "text"), // Alternative naming
|
||||
("file", "data"), // Alternative naming
|
||||
];
|
||||
|
||||
/// Extract path and content from various argument formats.
|
||||
fn extract_path_and_content(args: &serde_json::Value) -> (Option<&str>, Option<&str>) {
|
||||
if let Some(args_obj) = args.as_object() {
|
||||
// Format 1: Standard format with file_path and content
|
||||
if let (Some(path_val), Some(content_val)) =
|
||||
(args_obj.get("file_path"), args_obj.get("content"))
|
||||
{
|
||||
if let (Some(path), Some(content)) = (path_val.as_str(), content_val.as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
}
|
||||
}
|
||||
// Format 2: Anthropic-style with path and content
|
||||
if let (Some(path_val), Some(content_val)) =
|
||||
(args_obj.get("path"), args_obj.get("content"))
|
||||
{
|
||||
if let (Some(path), Some(content)) = (path_val.as_str(), content_val.as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
}
|
||||
}
|
||||
// Format 3: Alternative naming with filename and text
|
||||
if let (Some(path_val), Some(content_val)) =
|
||||
(args_obj.get("filename"), args_obj.get("text"))
|
||||
{
|
||||
if let (Some(path), Some(content)) = (path_val.as_str(), content_val.as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
}
|
||||
}
|
||||
// Format 4: Alternative naming with file and data
|
||||
if let (Some(path_val), Some(content_val)) = (args_obj.get("file"), args_obj.get("data")) {
|
||||
if let (Some(path), Some(content)) = (path_val.as_str(), content_val.as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
}
|
||||
}
|
||||
} else if let Some(args_array) = args.as_array() {
|
||||
// Format 5: Args might be an array [path, content]
|
||||
if args_array.len() >= 2 {
|
||||
if let (Some(path), Some(content)) = (args_array[0].as_str(), args_array[1].as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
match args {
|
||||
serde_json::Value::Object(obj) => {
|
||||
for &(path_key, content_key) in PATH_CONTENT_KEYS {
|
||||
if let (Some(p), Some(c)) = (obj.get(path_key), obj.get(content_key)) {
|
||||
if let (Some(path), Some(content)) = (p.as_str(), c.as_str()) {
|
||||
return (Some(path), Some(content));
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, None)
|
||||
}
|
||||
serde_json::Value::Array(arr) if arr.len() >= 2 => {
|
||||
match (arr[0].as_str(), arr[1].as_str()) {
|
||||
(Some(path), Some(content)) => (Some(path), Some(content)),
|
||||
_ => (None, None),
|
||||
}
|
||||
}
|
||||
_ => (None, None),
|
||||
}
|
||||
(None, None)
|
||||
}
|
||||
|
||||
/// Get image dimensions from raw bytes.
|
||||
|
||||
Reference in New Issue
Block a user