1#![deny(clippy::missing_errors_doc)]
21#![deny(clippy::missing_panics_doc)]
22#![deny(clippy::missing_safety_doc)]
23#![deny(missing_docs)]
24
25use std::ffi::OsString;
26use std::path::PathBuf;
27
28use clap::CommandFactory;
29use clap::Parser;
30use vortex::error::VortexExpect;
31use vortex::session::VortexSession;
32
33pub mod browse;
34pub mod convert;
35pub mod datafusion_helper;
36pub mod inspect;
37pub mod query;
38pub mod segment_tree;
39pub mod segments;
40pub mod tree;
41
42#[derive(clap::Parser)]
43#[command(version)]
44struct Cli {
45 #[clap(subcommand)]
46 command: Commands,
47}
48
49#[derive(Debug, clap::Subcommand)]
50enum Commands {
51 Tree(tree::TreeArgs),
53 Convert(#[command(flatten)] convert::ConvertArgs),
55 Browse { file: PathBuf },
57 Inspect(inspect::InspectArgs),
59 Query(query::QueryArgs),
61 Segments(segments::SegmentsArgs),
63}
64
65impl Commands {
66 fn file_path(&self) -> &PathBuf {
67 match self {
68 Commands::Tree(args) => match &args.mode {
69 tree::TreeMode::Array { file, .. } => file,
70 tree::TreeMode::Layout { file, .. } => file,
71 },
72 Commands::Browse { file } => file,
73 Commands::Convert(flags) => &flags.file,
74 Commands::Inspect(args) => &args.file,
75 Commands::Query(args) => &args.file,
76 Commands::Segments(args) => &args.file,
77 }
78 }
79}
80
81pub async fn launch(session: &VortexSession) -> anyhow::Result<()> {
89 launch_from(session, std::env::args_os()).await
90}
91
92pub async fn launch_from(
101 session: &VortexSession,
102 args: impl IntoIterator<Item = impl Into<OsString> + Clone>,
103) -> anyhow::Result<()> {
104 let _ = env_logger::try_init();
105
106 let cli = Cli::parse_from(args);
107
108 let path = cli.command.file_path();
109 if !std::fs::exists(path)? {
110 Cli::command()
111 .error(
112 clap::error::ErrorKind::Io,
113 format!(
114 "File '{}' does not exist.",
115 path.to_str().vortex_expect("file path")
116 ),
117 )
118 .exit()
119 }
120
121 match cli.command {
122 Commands::Tree(args) => tree::exec_tree(session, args).await?,
123 Commands::Convert(flags) => convert::exec_convert(session, flags).await?,
124 Commands::Browse { file } => browse::exec_tui(session, file).await?,
125 Commands::Inspect(args) => inspect::exec_inspect(session, args).await?,
126 Commands::Query(args) => query::exec_query(session, args).await?,
127 Commands::Segments(args) => segments::exec_segments(session, args).await?,
128 };
129
130 Ok(())
131}