idx-cli/src/main.rs
0xrsydn 2cdefeb7a6 feat(api): add MSN Finance as alternative data provider
Add MsnProvider implementing MarketDataProvider trait with quote,
fundamentals, and history support. Includes provider-aware config
(file/env/CLI), cache namespace isolation per provider, symbol ID
mapping via embedded TSV, OHLCV resampling, and comprehensive unit
+ integration tests with MSN fixture data.

Key changes:
- MsnProvider with quote, key-ratios, and chart endpoints
- ProviderKind enum (yahoo/msn) with config hierarchy support
- Provider-namespaced cache buckets to prevent cross-provider poisoning
- Provider-aware MockProvider loading correct fixtures per provider
- Integration tests for config round-trip and cache isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:19:10 +00:00

76 lines
2.1 KiB
Rust

pub mod analysis;
mod api;
mod cache;
mod cli;
mod config;
mod error;
mod output;
use clap::CommandFactory;
use clap::Parser;
use clap_complete::{generate, shells};
use crate::api::default_provider;
use crate::cli::{Cli, Commands};
use crate::config::IdxConfig;
use crate::error::IdxError;
use crate::output::emit_error;
fn main() {
if let Err(err) = run() {
std::process::exit(err.exit_code());
}
}
fn run() -> Result<(), IdxError> {
let cli = Cli::parse();
let config = match IdxConfig::load_with_cli(&cli) {
Ok(config) => config,
Err(err) => {
eprintln!("Error: {err}");
return Err(err);
}
};
match &cli.command {
Commands::Version => {
println!("{}", env!("CARGO_PKG_VERSION"));
}
Commands::Completions { shell } => {
let mut cmd = Cli::command();
let name = cmd.get_name().to_owned();
match shell {
cli::Shell::Bash => generate(shells::Bash, &mut cmd, name, &mut std::io::stdout()),
cli::Shell::Zsh => generate(shells::Zsh, &mut cmd, name, &mut std::io::stdout()),
cli::Shell::Fish => generate(shells::Fish, &mut cmd, name, &mut std::io::stdout()),
}
}
Commands::Stocks(stocks) => {
let provider = default_provider(config.provider, cli.verbose > 0);
if let Err(err) = cli::stocks::handle(
stocks,
&config,
provider.as_ref(),
cli.offline,
cli.no_cache,
) {
emit_error(&err, &config.output);
return Err(err);
}
}
Commands::Config(cfg) => {
if let Err(err) = cli::config::handle(cfg) {
emit_error(&err, &config.output);
return Err(err);
}
}
Commands::Cache(cache) => {
if let Err(err) = cli::cache::handle(cache) {
emit_error(&err, &config.output);
return Err(err);
}
}
}
Ok(())
}