use std::sync::Arc;
use anyhow::{Context, Result};
use schwab_api::{ClientConfig, SchwabClient, TraderApi};
use schwab_market_data::MarketDataApi;
use crate::cli::Cli;
use crate::mode::CliMode;
use crate::output::{OutputFormat, OutputSink};
use crate::safety::SafetyContext;
use crate::safety_config::SafetyConfig;
#[derive(Debug, Clone)]
pub struct RuntimeConfig {
pub mode: CliMode,
pub output: OutputFormat,
pub yes: bool,
pub dry_run: bool,
pub trust: bool,
pub safety: SafetyContext,
pub sink: OutputSink,
}
impl RuntimeConfig {
pub fn from_cli(cli: &Cli) -> Result<Self> {
let safety_cfg = SafetyConfig::load().context("Failed to load safety.json")?;
Ok(Self {
mode: cli.mode,
output: cli.effective_output(),
yes: cli.yes,
dry_run: cli.dry_run,
trust: cli.trust,
safety: SafetyContext::new(safety_cfg),
sink: OutputSink::stdout(),
})
}
pub fn emit(&self, envelope: crate::output::ResponseEnvelope) {
self.sink.write(&envelope, self.output);
}
pub fn is_tty(&self) -> bool {
use std::io::{stdin, stdout, IsTerminal};
stdin().is_terminal() && stdout().is_terminal()
}
pub fn is_interactive(&self) -> bool {
use std::io::stdout;
use std::io::IsTerminal;
self.mode.is_human() && stdout().is_terminal()
}
pub fn build_api(&self) -> Result<Arc<TraderApi>> {
let config = ClientConfig::from_env().context("Failed to load Schwab client config")?;
let client = SchwabClient::new(config);
Ok(Arc::new(TraderApi::new(client)))
}
pub fn build_market_api(&self) -> Result<Arc<MarketDataApi>> {
let config = ClientConfig::from_env().context("Failed to load Schwab client config")?;
let client = SchwabClient::new(config);
Ok(Arc::new(MarketDataApi::new(client)))
}
}