Skip to content

Commit c556494

Browse files
Copilot0xrinegade
andcommitted
Address code review feedback - refactor AI query handling and improve MarkdownRenderer
Co-authored-by: 0xrinegade <[email protected]>
1 parent 3f4e2ee commit c556494

File tree

2 files changed

+55
-32
lines changed

2 files changed

+55
-32
lines changed

src/main.rs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
#![allow(unused)]
33

44
use {
5-
crate::config::Config, // Added
5+
crate::config::Config,
66
crate::utils::diagnostics::DiagnosticCoordinator,
77
crate::utils::{dashboard, ebpf_deploy, examples, nodes, ssh_deploy, svm_info},
88
crate::utils::markdown_renderer::MarkdownRenderer,
99
clparse::parse_command_line,
1010
solana_client::rpc_client::RpcClient,
11-
solana_sdk::{native_token::Sol, pubkey::Pubkey, signature::Signer}, // Modified (removed CommitmentConfig) - bad formatting
12-
std::{process::exit, str::FromStr}, // Modified
11+
solana_sdk::{
12+
native_token::Sol,
13+
pubkey::Pubkey,
14+
signature::Signer
15+
},
16+
std::{process::exit, str::FromStr},
1317
};
1418

1519
// Helper function to handle the type mismatch between clap v2 and v4
@@ -57,22 +61,30 @@ async fn handle_ai_query(
5761
sub_matches: &clap::ArgMatches,
5862
app_matches: &clap::ArgMatches,
5963
) -> Result<(), Box<dyn std::error::Error>> {
60-
// For external subcommands, clap provides the additional arguments differently
61-
// We need to collect them from the raw args since clap doesn't know about them
62-
let args: Vec<String> = std::env::args().collect();
63-
64-
// Find where our subcommand starts and collect everything after osvm
65-
let mut query_parts = Vec::new();
66-
let mut found_osvm = false;
67-
68-
for arg in args.iter().skip(1) {
69-
// Skip the binary name
70-
if !found_osvm {
71-
found_osvm = true;
72-
}
73-
// Skip global flags like --help, --version, etc.
74-
if !arg.starts_with('-') {
75-
query_parts.push(arg.clone());
64+
// For external subcommands, clap collects additional arguments in subcommand_value
65+
// This is the proper way to handle external subcommands with clap
66+
let mut query_parts = vec![sub_command.to_string()];
67+
68+
// Get additional arguments from clap's external subcommand handling
69+
if let Some(external_args) = sub_matches.get_many::<String>("") {
70+
query_parts.extend(external_args.cloned());
71+
}
72+
73+
// If clap doesn't provide args (fallback), parse from environment
74+
// This maintains compatibility while documenting the limitation
75+
if query_parts.len() == 1 {
76+
let args: Vec<String> = std::env::args().collect();
77+
78+
// Collect non-flag arguments starting from the subcommand
79+
let mut found_subcommand = false;
80+
for arg in args.iter().skip(1) {
81+
if found_subcommand {
82+
if !arg.starts_with('-') {
83+
query_parts.push(arg.clone());
84+
}
85+
} else if arg == sub_command {
86+
found_subcommand = true;
87+
}
7688
}
7789
}
7890

@@ -94,11 +106,7 @@ async fn handle_ai_query(
94106
}
95107
// Render the response as markdown for better formatting
96108
let renderer = MarkdownRenderer::new();
97-
if let Err(e) = renderer.render(&response) {
98-
// Fallback to plain text if markdown rendering fails
99-
eprintln!("⚠️ Markdown rendering failed: {}", e);
100-
println!("{}", response);
101-
}
109+
renderer.render(&response);
102110
}
103111
Err(e) => {
104112
eprintln!("❌ AI query failed: {}", e);

src/utils/markdown_renderer.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use termimad::{MadSkin};
22

33
/// A markdown renderer for CLI output
4+
#[derive(Debug, Clone)]
45
pub struct MarkdownRenderer {
56
skin: MadSkin,
67
}
@@ -12,16 +13,24 @@ impl MarkdownRenderer {
1213
Self { skin }
1314
}
1415

16+
/// Create a new markdown renderer with custom theme configuration
17+
pub fn with_theme() -> Self {
18+
// For now, use default theme since termimad color API is complex
19+
// TODO: Implement proper color configuration once termimad usage is clarified
20+
let skin = MadSkin::default();
21+
Self { skin }
22+
}
23+
1524
/// Render markdown text to the terminal
16-
pub fn render(&self, markdown: &str) -> Result<(), Box<dyn std::error::Error>> {
25+
/// Note: termimad's print_text never actually fails, so we return unit type
26+
pub fn render(&self, markdown: &str) {
1727
self.skin.print_text(markdown);
18-
Ok(())
1928
}
2029

2130
/// Render markdown text and return as string (for testing)
22-
pub fn render_to_string(&self, markdown: &str) -> Result<String, Box<dyn std::error::Error>> {
31+
pub fn render_to_string(&self, markdown: &str) -> String {
2332
let fmt_text = self.skin.text(markdown, None);
24-
Ok(fmt_text.to_string())
33+
fmt_text.to_string()
2534
}
2635
}
2736

@@ -38,16 +47,22 @@ mod tests {
3847
#[test]
3948
fn test_markdown_renderer_creation() {
4049
let renderer = MarkdownRenderer::new();
41-
assert!(renderer.render_to_string("# Test").is_ok());
50+
let result = renderer.render_to_string("# Test");
51+
assert!(result.contains("Test"));
4252
}
4353

4454
#[test]
4555
fn test_basic_markdown_rendering() {
4656
let renderer = MarkdownRenderer::new();
4757
let markdown = "# Header\nSome **bold** text\n```rust\nlet x = 5;\n```";
48-
let result = renderer.render_to_string(markdown);
49-
assert!(result.is_ok());
50-
let output = result.unwrap();
58+
let output = renderer.render_to_string(markdown);
5159
assert!(output.contains("Header"));
5260
}
61+
62+
#[test]
63+
fn test_themed_renderer() {
64+
let renderer = MarkdownRenderer::with_theme();
65+
let result = renderer.render_to_string("# Themed Test");
66+
assert!(result.contains("Themed Test"));
67+
}
5368
}

0 commit comments

Comments
 (0)