Skip to content

Conversation

@SpeedSX
Copy link
Owner

@SpeedSX SpeedSX commented Oct 7, 2025

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

Adds a multi-value --parse PATH option to the Monitor, Logs, and Show CLI subcommands and threads the parse paths from main → commands (monitor_requests, show_logs, show_request_details) → display (print_full_request_body, print_request_details), updating function signatures and call sites. Display code now conditionally parses request bodies as JSON and prints values for specified paths (with handling for empty bodies, non-JSON input, missing paths, and optional full-body output). README documents the new option. Cargo.toml updates windows-sys from 0.61.1 to 0.61.2 (features unchanged).

Possibly related PRs

  • Modularization #3: Changes the same CLI, commands, and display functions to add and propagate a --parse option through call sites.
  • Feature/try colors #2: Modifies request-body rendering functions (print_full_request_body, print_request_details) and their APIs, directly overlapping the display logic changes in this PR.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description is entirely absent and thus provides no context or summary of the changes made, failing to describe any part of the changeset. Please add a brief description summarizing the JSON parsing feature additions and the dependency update to give reviewers the necessary context.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title “JSON Parsing feature” succinctly reflects the primary addition of JSON path parsing functionality across the CLI commands and aligns with the main change introduced in this pull request. It is clear, specific, and directly related to the core enhancement without unnecessary detail.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch parse

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/commands.rs (1)

141-208: Clippy is failing on show_logs (8 args).

CI is red (cargo clippy -- -D warnings) because show_logs now exceeds Clippy’s 7-arg limit. Matching what we already do for monitor_requests, add the allow attribute so the pipeline passes.

- pub async fn show_logs(
+#[allow(clippy::too_many_arguments)]
+pub async fn show_logs(
     client: &WebhookClient,
     config: &Config,
     token: &str,
🧹 Nitpick comments (1)
README.md (1)

251-263: Add a language hint to satisfy markdownlint.

markdownlint (MD040) is failing on this block because it lacks a language tag. Adding text (or another suitable language) clears the lint without altering rendering.

-```
+```text
 📄 REQUEST BODY
 ──────────────────────────────
 🧩 PARSED JSON FIELDS
 /user_id:
 12345
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35bbf49 and baf4a7e.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • Cargo.toml (1 hunks)
  • README.md (6 hunks)
  • src/cli.rs (3 hunks)
  • src/commands.rs (7 hunks)
  • src/display.rs (2 hunks)
  • src/main.rs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/commands.rs (1)
src/display.rs (2)
  • print_full_request_body (50-152)
  • print_request_details (154-267)
src/main.rs (1)
src/commands.rs (1)
  • show_request_details (210-228)
🪛 GitHub Actions: Rust
src/commands.rs

[error] 141-150: Clippy: this function has too many arguments (8/7). Command: 'cargo clippy -- -D warnings'.

src/display.rs

[error] 140-151: Clippy: this else { if .. } block can be collapsed. Command: 'cargo clippy -- -D warnings'.


[error] 209-241: Clippy: this if statement can be collapsed. Command: 'cargo clippy -- -D warnings'.

🪛 markdownlint-cli2 (0.18.1)
README.md

252-252: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between baf4a7e and 35ab513.

📒 Files selected for processing (3)
  • README.md (6 hunks)
  • src/commands.rs (8 hunks)
  • src/display.rs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/commands.rs (1)
src/display.rs (2)
  • print_full_request_body (50-150)
  • print_request_details (152-260)
🪛 markdownlint-cli2 (0.18.1)
README.md

252-252: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

Comment on lines +252 to +261
```
🧩 PARSED JSON FIELDS
/user_id:
12345
/metadata/ip:
"192.168.1.1"
/nonexistent/path: null (path not found)
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Specify code block language for lint compliance.

markdownlint (MD040) is flagging this fence because it lacks a language tag, and the pipeline fails whenever lint warnings are promoted to errors. Please add a language identifier (e.g., text) so the lint passes.

-```
+```text
 🧩 PARSED JSON FIELDS
 /user_id:
 12345
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

252-252: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In README.md around lines 252 to 261 the fenced code block lacks a language tag
which triggers markdownlint MD040; add an appropriate language identifier (for
example "text") immediately after the opening backticks so the fence becomes
```text and the lint will pass; ensure all similar fenced blocks in this section
are updated the same way.

Comment on lines +205 to 259
if parse_paths.is_empty() {
println!("{}", "REQUEST BODY".bright_cyan().bold());
println!("{}", "─".repeat(30).bright_black());
if let Some(body) = &request.message_object.body {
if body.trim().is_empty() {
println!("{}", "(empty)".bright_black());
} else {
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
let pretty_json = serde_json::to_string_pretty(&json).unwrap();
highlight_json(&pretty_json);
println!(); // Add newline after the highlighted JSON
}
Err(_) => {
println!("{}", body.bright_white());
}
}
Err(_) => {
println!("{}", body.bright_white());
}
} else {
println!("{}", "(no body)".bright_black());
}
} else if let Some(body) = &request.message_object.body
&& !body.trim().is_empty()
{
// Parse and display only specific JSON paths
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
println!("{}", "PARSED JSON FIELDS".bright_green().bold());
for path in parse_paths {
match json.pointer(path) {
Some(value) => {
println!("{}:", path.bright_blue());
let pretty_value = serde_json::to_string_pretty(value).unwrap();
highlight_json(&pretty_value);
println!();
}
None => {
println!(
"{}: {} (path not found)",
path.bright_blue(),
"null".bright_red()
);
}
}
}
}
Err(_) => {
println!(
"{}",
"Body is not valid JSON, cannot parse paths".bright_red()
);
println!("{}", body.bright_white());
}
}
} else {
println!("{}", "(no body)".bright_black());
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle parse paths when the body is empty or missing.

With --parse active, print_request_details currently emits nothing if the body is empty ("") or absent (None) because the guard && !body.trim().is_empty() skips the entire branch. That regresses UX compared to print_full_request_body, which shows explicit (empty body) / (no body) messages. Please mirror that handling so the parsed-fields section still renders.

-    } else if let Some(body) = &request.message_object.body
-        && !body.trim().is_empty()
-    {
-        // Parse and display only specific JSON paths
-        match serde_json::from_str::<serde_json::Value>(body) {
-            Ok(json) => {
-                println!("{}", "PARSED JSON FIELDS".bright_green().bold());
-                for path in parse_paths {
-                    match json.pointer(path) {
-                        Some(value) => {
-                            println!("{}:", path.bright_blue());
-                            let pretty_value = serde_json::to_string_pretty(value).unwrap();
-                            highlight_json(&pretty_value);
-                            println!();
-                        }
-                        None => {
-                            println!(
-                                "{}: {} (path not found)",
-                                path.bright_blue(),
-                                "null".bright_red()
-                            );
-                        }
-                    }
-                }
-            }
-            Err(_) => {
-                println!(
-                    "{}",
-                    "Body is not valid JSON, cannot parse paths".bright_red()
-                );
-                println!("{}", body.bright_white());
-            }
-        }
-    }
+    } else if let Some(body) = &request.message_object.body {
+        if body.trim().is_empty() {
+            println!("{}", "PARSED JSON FIELDS".bright_green().bold());
+            println!("{}", "(empty body)".bright_black());
+        } else {
+            // Parse and display only specific JSON paths
+            match serde_json::from_str::<serde_json::Value>(body) {
+                Ok(json) => {
+                    println!("{}", "PARSED JSON FIELDS".bright_green().bold());
+                    for path in parse_paths {
+                        match json.pointer(path) {
+                            Some(value) => {
+                                println!("{}:", path.bright_blue());
+                                let pretty_value =
+                                    serde_json::to_string_pretty(value).unwrap();
+                                highlight_json(&pretty_value);
+                                println!();
+                            }
+                            None => {
+                                println!(
+                                    "{}: {} (path not found)",
+                                    path.bright_blue(),
+                                    "null".bright_red()
+                                );
+                            }
+                        }
+                    }
+                }
+                Err(_) => {
+                    println!(
+                        "{}",
+                        "Body is not valid JSON, cannot parse paths".bright_red()
+                    );
+                    println!("{}", body.bright_white());
+                }
+            }
+        }
+    } else {
+        println!("{}", "PARSED JSON FIELDS".bright_green().bold());
+        println!("{}", "(no body)".bright_black());
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if parse_paths.is_empty() {
println!("{}", "REQUEST BODY".bright_cyan().bold());
println!("{}", "─".repeat(30).bright_black());
if let Some(body) = &request.message_object.body {
if body.trim().is_empty() {
println!("{}", "(empty)".bright_black());
} else {
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
let pretty_json = serde_json::to_string_pretty(&json).unwrap();
highlight_json(&pretty_json);
println!(); // Add newline after the highlighted JSON
}
Err(_) => {
println!("{}", body.bright_white());
}
}
Err(_) => {
println!("{}", body.bright_white());
}
} else {
println!("{}", "(no body)".bright_black());
}
} else if let Some(body) = &request.message_object.body
&& !body.trim().is_empty()
{
// Parse and display only specific JSON paths
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
println!("{}", "PARSED JSON FIELDS".bright_green().bold());
for path in parse_paths {
match json.pointer(path) {
Some(value) => {
println!("{}:", path.bright_blue());
let pretty_value = serde_json::to_string_pretty(value).unwrap();
highlight_json(&pretty_value);
println!();
}
None => {
println!(
"{}: {} (path not found)",
path.bright_blue(),
"null".bright_red()
);
}
}
}
}
Err(_) => {
println!(
"{}",
"Body is not valid JSON, cannot parse paths".bright_red()
);
println!("{}", body.bright_white());
}
}
} else {
println!("{}", "(no body)".bright_black());
}
if parse_paths.is_empty() {
println!("{}", "REQUEST BODY".bright_cyan().bold());
println!("{}", "─".repeat(30).bright_black());
if let Some(body) = &request.message_object.body {
if body.trim().is_empty() {
println!("{}", "(empty)".bright_black());
} else {
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
let pretty_json = serde_json::to_string_pretty(&json).unwrap();
highlight_json(&pretty_json);
println!(); // Add newline after the highlighted JSON
}
Err(_) => {
println!("{}", body.bright_white());
}
}
}
} else {
println!("{}", "(no body)".bright_black());
}
} else if let Some(body) = &request.message_object.body {
if body.trim().is_empty() {
println!("{}", "PARSED JSON FIELDS".bright_green().bold());
println!("{}", "(empty body)".bright_black());
} else {
// Parse and display only specific JSON paths
match serde_json::from_str::<serde_json::Value>(body) {
Ok(json) => {
println!("{}", "PARSED JSON FIELDS".bright_green().bold());
for path in parse_paths {
match json.pointer(path) {
Some(value) => {
println!("{}:", path.bright_blue());
let pretty_value =
serde_json::to_string_pretty(value).unwrap();
highlight_json(&pretty_value);
println!();
}
None => {
println!(
"{}: {} (path not found)",
path.bright_blue(),
"null".bright_red()
);
}
}
}
}
Err(_) => {
println!(
"{}",
"Body is not valid JSON, cannot parse paths".bright_red()
);
println!("{}", body.bright_white());
}
}
}
} else {
println!("{}", "PARSED JSON FIELDS".bright_green().bold());
println!("{}", "(no body)".bright_black());
}
🤖 Prompt for AI Agents
In src/display.rs around lines 205 to 259, the branch that handles --parse
currently skips when the body is None or empty because of the guard &&
!body.trim().is_empty(); change this so the parsed-fields branch always runs
when parse_paths is non-empty, then match on request.message_object.body: if
None print the "PARSED JSON FIELDS" header and a "(no body)" message
(bright_black) and for each requested path print it as not found (e.g. ": null
(path not found)"); if Some(body) and body.trim().is_empty() print the header
and "(empty)" (bright_black) and similarly mark paths as not found; only attempt
serde_json::from_str for non-empty bodies and keep the existing
pretty-print/highlight or error handling for invalid JSON.

@SpeedSX SpeedSX merged commit b035105 into main Oct 7, 2025
2 checks passed
@SpeedSX SpeedSX deleted the parse branch October 7, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants