@@ -164,6 +164,17 @@ struct UsageData {
164164 total_tokens : Option < u32 > ,
165165}
166166
167+ struct VerboseContext < ' a > {
168+ provider : Provider ,
169+ model : & ' a str ,
170+ output_format : OutputFormat ,
171+ dry_run : bool ,
172+ show_usage : bool ,
173+ prompt_source : PromptSource ,
174+ messages : & ' a [ ChatMessage ] ,
175+ options : & ' a AskOptions ,
176+ }
177+
167178pub async fn run ( cli : AskArgs ) -> Result < ( ) , String > {
168179 if cli. version {
169180 println ! ( "{}" , render_version( ) ) ;
@@ -200,16 +211,16 @@ pub async fn run(cli: AskArgs) -> Result<(), String> {
200211 let messages = build_messages ( non_empty ( system. as_deref ( ) ) , & prompt) ;
201212
202213 if cli. verbose && !cli. quiet {
203- log_verbose (
214+ log_verbose ( VerboseContext {
204215 provider,
205- & model,
216+ model : & model,
206217 output_format,
207- cli. dry_run ,
218+ dry_run : cli. dry_run ,
208219 show_usage,
209- main_prompt. source ,
210- & messages,
211- & options,
212- ) ;
220+ prompt_source : main_prompt. source ,
221+ messages : & messages,
222+ options : & options,
223+ } ) ;
213224 }
214225
215226 if cli. dry_run {
@@ -299,15 +310,15 @@ pub async fn run(cli: AskArgs) -> Result<(), String> {
299310}
300311
301312fn write_output ( path : & Path , content : & str ) -> Result < ( ) , String > {
302- if let Some ( parent) = path. parent ( ) {
303- if !parent. as_os_str ( ) . is_empty ( ) {
304- fs :: create_dir_all ( parent ) . map_err ( |err| {
305- format ! (
306- "Failed to create output directory '{}': {err}" ,
307- parent . display ( )
308- )
309- } ) ? ;
310- }
313+ if let Some ( parent) = path. parent ( )
314+ && !parent. as_os_str ( ) . is_empty ( )
315+ {
316+ fs :: create_dir_all ( parent ) . map_err ( |err| {
317+ format ! (
318+ "Failed to create output directory '{}': {err}" ,
319+ parent . display ( )
320+ )
321+ } ) ? ;
311322 }
312323
313324 let now = SystemTime :: now ( )
@@ -381,23 +392,23 @@ fn json_usage(usage: &UsageData) -> Option<JsonUsage> {
381392}
382393
383394fn print_usage ( usage : & Option < UsageData > , latency_ms : u128 ) {
384- if let Some ( usage) = usage {
385- if let Some ( usage) = json_usage ( usage) {
386- eprintln ! (
387- "usage: prompt_tokens={} completion_tokens={} total_tokens={} latency_ms={}" ,
388- usage
389- . prompt_tokens
390- . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
391- usage
392- . completion_tokens
393- . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
394- usage
395- . total_tokens
396- . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
397- latency_ms
398- ) ;
399- return ;
400- }
395+ if let Some ( usage) = usage
396+ && let Some ( usage) = json_usage ( usage)
397+ {
398+ eprintln ! (
399+ "usage: prompt_tokens={} completion_tokens={} total_tokens={} latency_ms={}" ,
400+ usage
401+ . prompt_tokens
402+ . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
403+ usage
404+ . completion_tokens
405+ . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
406+ usage
407+ . total_tokens
408+ . map_or_else ( || "n/a" . to_string ( ) , |value| value . to_string ( ) ) ,
409+ latency_ms
410+ ) ;
411+ return ;
401412 }
402413
403414 eprintln ! ( "usage: unavailable latency_ms={latency_ms}" ) ;
@@ -426,18 +437,18 @@ fn build_messages(system: Option<&str>, prompt: &str) -> Vec<ChatMessage> {
426437fn compose_prompt ( preprompt : Option < & str > , main_prompt : & str , postprompt : Option < & str > ) -> String {
427438 let mut parts = Vec :: new ( ) ;
428439
429- if let Some ( pre) = preprompt {
430- if !pre. trim ( ) . is_empty ( ) {
431- parts . push ( pre . to_string ( ) ) ;
432- }
440+ if let Some ( pre) = preprompt
441+ && !pre. trim ( ) . is_empty ( )
442+ {
443+ parts . push ( pre . to_string ( ) ) ;
433444 }
434445
435446 parts. push ( main_prompt. to_string ( ) ) ;
436447
437- if let Some ( post) = postprompt {
438- if !post. trim ( ) . is_empty ( ) {
439- parts . push ( post . to_string ( ) ) ;
440- }
448+ if let Some ( post) = postprompt
449+ && !post. trim ( ) . is_empty ( )
450+ {
451+ parts . push ( post . to_string ( ) ) ;
441452 }
442453
443454 parts. join ( "\n \n " )
@@ -515,12 +526,12 @@ fn resolve_temperature(
515526 profile. temperature
516527 } ;
517528
518- if let Some ( value) = temperature {
519- if !( 0.0 ..=2.0 ) . contains ( & value) {
520- return Err ( format ! (
521- "Invalid temperature {value}. Must be in [0.0, 2.0]."
522- ) ) ;
523- }
529+ if let Some ( value) = temperature
530+ && !( 0.0 ..=2.0 ) . contains ( & value)
531+ {
532+ return Err ( format ! (
533+ "Invalid temperature {value}. Must be in [0.0, 2.0]."
534+ ) ) ;
524535 }
525536
526537 Ok ( temperature)
@@ -542,10 +553,10 @@ fn resolve_max_tokens(
542553 profile. max_tokens
543554 } ;
544555
545- if let Some ( value) = max_tokens {
546- if value == 0 {
547- return Err ( "Invalid max tokens 0. Must be > 0." . to_string ( ) ) ;
548- }
556+ if let Some ( value) = max_tokens
557+ && value == 0
558+ {
559+ return Err ( "Invalid max tokens 0. Must be > 0." . to_string ( ) ) ;
549560 }
550561
551562 Ok ( max_tokens)
@@ -567,10 +578,10 @@ fn resolve_timeout(
567578 profile. timeout
568579 } ;
569580
570- if let Some ( value) = timeout {
571- if value == 0 {
572- return Err ( "Invalid timeout 0. Must be > 0 seconds." . to_string ( ) ) ;
573- }
581+ if let Some ( value) = timeout
582+ && value == 0
583+ {
584+ return Err ( "Invalid timeout 0. Must be > 0 seconds." . to_string ( ) ) ;
574585 }
575586
576587 Ok ( timeout)
@@ -670,48 +681,43 @@ fn resolve_prompt(cli_prompt: Option<String>) -> Result<PromptInput, String> {
670681 } )
671682}
672683
673- fn log_verbose (
674- provider : Provider ,
675- model : & str ,
676- output_format : OutputFormat ,
677- dry_run : bool ,
678- show_usage : bool ,
679- prompt_source : PromptSource ,
680- messages : & [ ChatMessage ] ,
681- options : & AskOptions ,
682- ) {
683- let api_key_present = provider:: is_api_key_present ( provider) ;
684- let total_chars: usize = messages
684+ fn log_verbose ( context : VerboseContext < ' _ > ) {
685+ let api_key_present = provider:: is_api_key_present ( context. provider ) ;
686+ let total_chars: usize = context
687+ . messages
685688 . iter ( )
686689 . map ( |message| message. content . chars ( ) . count ( ) )
687690 . sum ( ) ;
688691
689692 eprintln ! (
690693 "verbose: provider={} endpoint={} model={} output={} dry_run={} show_usage={} prompt_source={} messages={} chars={} api_key_present={}" ,
691- provider. as_str( ) ,
692- provider:: endpoint( provider) ,
693- model,
694- output_format. as_str( ) ,
695- dry_run,
696- show_usage,
697- prompt_source. as_str( ) ,
698- messages. len( ) ,
694+ context . provider. as_str( ) ,
695+ provider:: endpoint( context . provider) ,
696+ context . model,
697+ context . output_format. as_str( ) ,
698+ context . dry_run,
699+ context . show_usage,
700+ context . prompt_source. as_str( ) ,
701+ context . messages. len( ) ,
699702 total_chars,
700703 api_key_present
701704 ) ;
702705 eprintln ! (
703706 "verbose: options temperature={} max_tokens={} timeout_secs={} retries={} retry_delay_ms={} backoff=exponential" ,
704- options
707+ context
708+ . options
705709 . temperature
706710 . map_or_else( || "n/a" . to_string( ) , |value| value. to_string( ) ) ,
707- options
711+ context
712+ . options
708713 . max_tokens
709714 . map_or_else( || "n/a" . to_string( ) , |value| value. to_string( ) ) ,
710- options
715+ context
716+ . options
711717 . timeout_secs
712718 . map_or_else( || "n/a" . to_string( ) , |value| value. to_string( ) ) ,
713- options. retries,
714- options. retry_delay_ms
719+ context . options. retries,
720+ context . options. retry_delay_ms
715721 ) ;
716722}
717723
0 commit comments