use claude_core::paths::ClaudePaths;
use error_tools::{ Error, Result };
use super::parse::next_value;
use super::env::{ env_bool, env_str };
#[ derive( Default ) ]
pub( super ) struct IsolatedArgs
{
pub( super ) creds_path : String,
pub( super ) timeout_secs : u64,
pub( super ) trace : bool,
pub( super ) message : Option< String >,
pub( super ) passthrough_args : Vec< String >,
}
pub( super ) struct RefreshArgs
{
pub( super ) creds_path : String,
pub( super ) timeout_secs : u64,
pub( super ) trace : bool,
}
fn parse_timeout_secs( raw : &str ) -> Result< u64 >
{
raw.parse::< u64 >().map_err( | _ |
Error::msg( format!(
"invalid --timeout value: {raw}\n\
Expected non-negative integer"
) )
)
}
fn apply_cred_env_vars(
creds_path : &mut String,
timeout_secs : &mut u64,
default_timeout : u64,
trace : &mut bool,
)
{
if creds_path.is_empty()
{
*creds_path = env_str( "CLR_CREDS" ).unwrap_or_default();
}
if creds_path.is_empty()
{
if let Some( paths ) = ClaudePaths::new()
{
*creds_path = paths.credentials_file().to_string_lossy().into_owned();
}
}
if *timeout_secs == default_timeout
{
if let Some( v ) = env_str( "CLR_TIMEOUT" )
{
if let Ok( secs ) = v.parse::< u64 >() { *timeout_secs = secs; }
}
}
if !*trace { *trace = env_bool( "CLR_TRACE" ); }
}
pub( super ) fn parse_isolated_args( tokens : &[ String ] ) -> Result< IsolatedArgs >
{
let mut creds_path : Option< String > = None;
let mut timeout_secs : u64 = 30;
let mut trace : bool = false;
let mut message_parts : Vec< String > = Vec::new();
let mut passthrough_args : Vec< String > = Vec::new();
let mut i = 0;
while i < tokens.len()
{
let token = tokens[ i ].as_str();
match token
{
"--" =>
{
passthrough_args.extend( tokens[ i + 1 .. ].iter().cloned() );
break;
}
"--creds" =>
{
creds_path = Some( next_value( tokens, i + 1, "--creds" )?.to_string() );
i += 1;
}
"--timeout" =>
{
let raw = next_value( tokens, i + 1, "--timeout" )?;
timeout_secs = parse_timeout_secs( raw )?;
i += 1;
}
"--trace" =>
{
trace = true;
}
"-h" | "--help" => { super::help::print_isolated_help(); }
s if s.starts_with( '-' ) =>
{
return Err( Error::msg( format!(
"unknown option: {s}\nRun with --help for usage."
) ) );
}
_ =>
{
if !tokens[ i ].is_empty() { message_parts.push( tokens[ i ].clone() ); }
}
}
i += 1;
}
let creds_path = creds_path.unwrap_or_default();
let message = if message_parts.is_empty() { None } else { Some( message_parts.join( " " ) ) };
Ok( IsolatedArgs { creds_path, timeout_secs, trace, message, passthrough_args } )
}
pub( super ) fn apply_isolated_env_vars( parsed : &mut IsolatedArgs )
{
apply_cred_env_vars( &mut parsed.creds_path, &mut parsed.timeout_secs, 30, &mut parsed.trace );
}
pub( super ) fn parse_refresh_args( tokens : &[ String ] ) -> Result< RefreshArgs >
{
let mut creds_path : Option< String > = None;
let mut timeout_secs : u64 = 45;
let mut trace : bool = false;
let mut i = 0;
while i < tokens.len()
{
let token = tokens[ i ].as_str();
match token
{
"--creds" =>
{
creds_path = Some( next_value( tokens, i + 1, "--creds" )?.to_string() );
i += 1;
}
"--timeout" =>
{
let raw = next_value( tokens, i + 1, "--timeout" )?;
timeout_secs = parse_timeout_secs( raw )?;
i += 1;
}
"--trace" =>
{
trace = true;
}
"-h" | "--help" => { super::help::print_refresh_help(); }
s if s.starts_with( '-' ) =>
{
return Err( Error::msg( format!(
"unknown option: {s}\nRun with --help for usage."
) ) );
}
_ => {} }
i += 1;
}
let creds_path = creds_path.unwrap_or_default();
Ok( RefreshArgs { creds_path, timeout_secs, trace } )
}
pub( super ) fn apply_refresh_env_vars( parsed : &mut RefreshArgs )
{
apply_cred_env_vars( &mut parsed.creds_path, &mut parsed.timeout_secs, 45, &mut parsed.trace );
}