vortex_tui/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Vortex TUI library for interactively browsing and inspecting Vortex files.
5//!
6//! This crate provides both a CLI tool (`vx`) and a library API for working with Vortex files.
7//! Users can bring their own [`VortexSession`] to enable custom encodings and extensions.
8//!
9//! # Example
10//!
11//! ```ignore
12//! use vortex::session::VortexSession;
13//! use vortex::io::session::RuntimeSessionExt;
14//! use vortex_tui::browse;
15//!
16//! let session = VortexSession::default().with_tokio();
17//! browse::exec_tui(&session, "my_file.vortex").await?;
18//! ```
19
20#![deny(clippy::missing_errors_doc)]
21#![deny(clippy::missing_panics_doc)]
22#![deny(clippy::missing_safety_doc)]
23#![deny(missing_docs)]
24
25use std::path::PathBuf;
26
27use clap::CommandFactory;
28use clap::Parser;
29use vortex::error::VortexExpect;
30use vortex::session::VortexSession;
31
32pub mod browse;
33pub mod convert;
34pub mod inspect;
35pub mod tree;
36
37#[derive(clap::Parser)]
38#[command(version)]
39struct Cli {
40    #[clap(subcommand)]
41    command: Commands,
42}
43
44#[derive(Debug, clap::Subcommand)]
45enum Commands {
46    /// Print tree views of a Vortex file (layout tree or array tree)
47    Tree(tree::TreeArgs),
48    /// Convert a Parquet file to a Vortex file. Chunking occurs on Parquet RowGroup boundaries.
49    Convert(#[command(flatten)] convert::ConvertArgs),
50    /// Interactively browse the Vortex file.
51    Browse { file: PathBuf },
52    /// Inspect Vortex file footer and metadata
53    Inspect(inspect::InspectArgs),
54}
55
56impl Commands {
57    fn file_path(&self) -> &PathBuf {
58        match self {
59            Commands::Tree(args) => match &args.mode {
60                tree::TreeMode::Array { file } => file,
61                tree::TreeMode::Layout { file, .. } => file,
62            },
63            Commands::Browse { file } => file,
64            Commands::Convert(flags) => &flags.file,
65            Commands::Inspect(args) => &args.file,
66        }
67    }
68}
69
70/// Main entrypoint for `vx` that launches a [`VortexSession`].
71///
72/// # Errors
73///
74/// Raises any errors from subcommands.
75pub async fn launch(session: &VortexSession) -> anyhow::Result<()> {
76    env_logger::init();
77
78    let cli = Cli::parse();
79
80    let path = cli.command.file_path();
81    if !std::fs::exists(path)? {
82        Cli::command()
83            .error(
84                clap::error::ErrorKind::Io,
85                format!(
86                    "File '{}' does not exist.",
87                    path.to_str().vortex_expect("file path")
88                ),
89            )
90            .exit()
91    }
92
93    match cli.command {
94        Commands::Tree(args) => tree::exec_tree(session, args).await?,
95        Commands::Convert(flags) => convert::exec_convert(session, flags).await?,
96        Commands::Browse { file } => browse::exec_tui(session, file).await?,
97        Commands::Inspect(args) => inspect::exec_inspect(session, args).await?,
98    };
99
100    Ok(())
101}