From 30ba8c52b84fbf9ff4c338a4763c7e778565a814 Mon Sep 17 00:00:00 2001 From: Jiayu Liu Date: Wed, 2 Feb 2022 16:29:10 +0800 Subject: [PATCH] upgrade clap --- integration-testing/Cargo.toml | 2 +- .../src/bin/arrow-file-to-stream.rs | 18 ++-- .../src/bin/arrow-json-integration-test.rs | 72 +++++++------- .../src/bin/flight-test-integration-client.rs | 61 +++++++----- .../src/bin/flight-test-integration-server.rs | 39 ++++---- .../auth_basic_proto.rs | 2 +- .../integration_test.rs | 2 +- .../src/flight_client_scenarios/middleware.rs | 2 +- .../src/flight_server_scenarios.rs | 2 +- .../auth_basic_proto.rs | 2 +- .../integration_test.rs | 2 +- .../src/flight_server_scenarios/middleware.rs | 2 +- parquet/Cargo.toml | 2 +- parquet/src/bin/parquet-read.rs | 94 +++++++------------ parquet/src/bin/parquet-rowcount.rs | 58 +++++------- parquet/src/bin/parquet-schema.rs | 62 ++++-------- 16 files changed, 181 insertions(+), 241 deletions(-) diff --git a/integration-testing/Cargo.toml b/integration-testing/Cargo.toml index cbb6ca675d2f..03c2abf0b6e6 100644 --- a/integration-testing/Cargo.toml +++ b/integration-testing/Cargo.toml @@ -34,7 +34,7 @@ logging = ["tracing-subscriber"] arrow = { path = "../arrow" } arrow-flight = { path = "../arrow-flight" } async-trait = "0.1.41" -clap = "2.33" +clap = { version = "3", features = ["derive", "env"] } futures = "0.3" hex = "0.4" prost = "0.9" diff --git a/integration-testing/src/bin/arrow-file-to-stream.rs b/integration-testing/src/bin/arrow-file-to-stream.rs index d6bb0428c0f6..fbc217aab858 100644 --- a/integration-testing/src/bin/arrow-file-to-stream.rs +++ b/integration-testing/src/bin/arrow-file-to-stream.rs @@ -15,18 +15,22 @@ // specific language governing permissions and limitations // under the License. -use std::env; -use std::fs::File; -use std::io::{self, BufReader}; - use arrow::error::Result; use arrow::ipc::reader::FileReader; use arrow::ipc::writer::StreamWriter; +use clap::Parser; +use std::fs::File; +use std::io::{self, BufReader}; + +#[derive(Debug, Parser)] +#[clap(author, version, about("Read an arrow file and stream to stdout"), long_about = None)] +struct Args { + file_name: String, +} fn main() -> Result<()> { - let args: Vec = env::args().collect(); - let filename = &args[1]; - let f = File::open(filename)?; + let args = Args::parse(); + let f = File::open(&args.file_name)?; let reader = BufReader::new(f); let mut reader = FileReader::try_new(reader)?; let schema = reader.schema(); diff --git a/integration-testing/src/bin/arrow-json-integration-test.rs b/integration-testing/src/bin/arrow-json-integration-test.rs index 257802028b20..81200b99f982 100644 --- a/integration-testing/src/bin/arrow-json-integration-test.rs +++ b/integration-testing/src/bin/arrow-json-integration-test.rs @@ -15,52 +15,46 @@ // specific language governing permissions and limitations // under the License. -use std::fs::File; - -use clap::{App, Arg}; - use arrow::error::{ArrowError, Result}; use arrow::ipc::reader::FileReader; use arrow::ipc::writer::FileWriter; use arrow::util::integration_util::*; use arrow_integration_testing::read_json_file; +use clap::Parser; +use std::fs::File; + +#[derive(clap::ArgEnum, Debug, Clone)] +#[clap(rename_all = "SCREAMING_SNAKE_CASE")] +enum Mode { + ArrowToJson, + JsonToArrow, + Validate, +} + +#[derive(Debug, Parser)] +#[clap(author, version, about("rust arrow-json-integration-test"), long_about = None)] +struct Args { + #[clap(short, long)] + integration: bool, + #[clap(short, long, help("Path to ARROW file"))] + arrow: String, + #[clap(short, long, help("Path to JSON file"))] + json: String, + #[clap(arg_enum, short, long, default_value_t = Mode::Validate, help="Mode of integration testing tool")] + mode: Mode, + #[clap(short, long)] + verbose: bool, +} fn main() -> Result<()> { - let matches = App::new("rust arrow-json-integration-test") - .arg(Arg::with_name("integration") - .long("integration")) - .arg(Arg::with_name("arrow") - .long("arrow") - .help("path to ARROW file") - .takes_value(true)) - .arg(Arg::with_name("json") - .long("json") - .help("path to JSON file") - .takes_value(true)) - .arg(Arg::with_name("mode") - .long("mode") - .help("mode of integration testing tool (ARROW_TO_JSON, JSON_TO_ARROW, VALIDATE)") - .takes_value(true) - .default_value("VALIDATE")) - .arg(Arg::with_name("verbose") - .long("verbose") - .help("enable/disable verbose mode")) - .get_matches(); - - let arrow_file = matches - .value_of("arrow") - .expect("must provide path to arrow file"); - let json_file = matches - .value_of("json") - .expect("must provide path to json file"); - let mode = matches.value_of("mode").unwrap(); - let verbose = true; //matches.value_of("verbose").is_some(); - - match mode { - "JSON_TO_ARROW" => json_to_arrow(json_file, arrow_file, verbose), - "ARROW_TO_JSON" => arrow_to_json(arrow_file, json_file, verbose), - "VALIDATE" => validate(arrow_file, json_file, verbose), - _ => panic!("mode {} not supported", mode), + let args = Args::parse(); + let arrow_file = args.arrow; + let json_file = args.json; + let verbose = args.verbose; + match args.mode { + Mode::JsonToArrow => json_to_arrow(&json_file, &arrow_file, verbose), + Mode::ArrowToJson => arrow_to_json(&arrow_file, &json_file, verbose), + Mode::Validate => validate(&arrow_file, &json_file, verbose), } } diff --git a/integration-testing/src/bin/flight-test-integration-client.rs b/integration-testing/src/bin/flight-test-integration-client.rs index 1901553109f9..f380627b04c5 100644 --- a/integration-testing/src/bin/flight-test-integration-client.rs +++ b/integration-testing/src/bin/flight-test-integration-client.rs @@ -16,44 +16,53 @@ // under the License. use arrow_integration_testing::flight_client_scenarios; - -use clap::{App, Arg}; - +use clap::Parser; type Error = Box; type Result = std::result::Result; +#[derive(clap::ArgEnum, Debug, Clone)] +enum Scenario { + Middleware, + #[clap(name = "auth:basic_proto")] + AuthBasicProto, +} + +#[derive(Debug, Parser)] +#[clap(author, version, about("rust flight-test-integration-client"), long_about = None)] +struct Args { + #[clap(long, help = "host of flight server")] + host: String, + #[clap(long, help = "port of flight server")] + port: u16, + #[clap( + short, + long, + help = "path to the descriptor file, only used when scenario is not provided" + )] + path: Option, + #[clap(long, arg_enum)] + scenario: Option, +} + #[tokio::main] async fn main() -> Result { #[cfg(feature = "logging")] tracing_subscriber::fmt::init(); - let matches = App::new("rust flight-test-integration-client") - .arg(Arg::with_name("host").long("host").takes_value(true)) - .arg(Arg::with_name("port").long("port").takes_value(true)) - .arg(Arg::with_name("path").long("path").takes_value(true)) - .arg( - Arg::with_name("scenario") - .long("scenario") - .takes_value(true), - ) - .get_matches(); - - let host = matches.value_of("host").expect("Host is required"); - let port = matches.value_of("port").expect("Port is required"); + let args = Args::parse(); + let host = args.host; + let port = args.port; - match matches.value_of("scenario") { - Some("middleware") => { - flight_client_scenarios::middleware::run_scenario(host, port).await? + match args.scenario { + Some(Scenario::Middleware) => { + flight_client_scenarios::middleware::run_scenario(&host, port).await? } - Some("auth:basic_proto") => { - flight_client_scenarios::auth_basic_proto::run_scenario(host, port).await? + Some(Scenario::AuthBasicProto) => { + flight_client_scenarios::auth_basic_proto::run_scenario(&host, port).await? } - Some(scenario_name) => unimplemented!("Scenario not found: {}", scenario_name), None => { - let path = matches - .value_of("path") - .expect("Path is required if scenario is not specified"); - flight_client_scenarios::integration_test::run_scenario(host, port, path) + let path = args.path.expect("No path is given"); + flight_client_scenarios::integration_test::run_scenario(&host, port, &path) .await?; } } diff --git a/integration-testing/src/bin/flight-test-integration-server.rs b/integration-testing/src/bin/flight-test-integration-server.rs index b1b280743c3c..6ed22ad81d90 100644 --- a/integration-testing/src/bin/flight-test-integration-server.rs +++ b/integration-testing/src/bin/flight-test-integration-server.rs @@ -15,38 +15,43 @@ // specific language governing permissions and limitations // under the License. -use clap::{App, Arg}; - use arrow_integration_testing::flight_server_scenarios; +use clap::Parser; type Error = Box; type Result = std::result::Result; +#[derive(clap::ArgEnum, Debug, Clone)] +enum Scenario { + Middleware, + #[clap(name = "auth:basic_proto")] + AuthBasicProto, +} + +#[derive(Debug, Parser)] +#[clap(author, version, about("rust flight-test-integration-server"), long_about = None)] +struct Args { + #[clap(long)] + port: u16, + #[clap(long, arg_enum)] + scenario: Option, +} + #[tokio::main] async fn main() -> Result { #[cfg(feature = "logging")] tracing_subscriber::fmt::init(); - let matches = App::new("rust flight-test-integration-server") - .about("Integration testing server for Flight.") - .arg(Arg::with_name("port").long("port").takes_value(true)) - .arg( - Arg::with_name("scenario") - .long("scenario") - .takes_value(true), - ) - .get_matches(); - - let port = matches.value_of("port").unwrap_or("0"); + let args = Args::parse(); + let port = args.port; - match matches.value_of("scenario") { - Some("middleware") => { + match args.scenario { + Some(Scenario::Middleware) => { flight_server_scenarios::middleware::scenario_setup(port).await? } - Some("auth:basic_proto") => { + Some(Scenario::AuthBasicProto) => { flight_server_scenarios::auth_basic_proto::scenario_setup(port).await? } - Some(scenario_name) => unimplemented!("Scenario not found: {}", scenario_name), None => { flight_server_scenarios::integration_test::scenario_setup(port).await?; } diff --git a/integration-testing/src/flight_client_scenarios/auth_basic_proto.rs b/integration-testing/src/flight_client_scenarios/auth_basic_proto.rs index 5e8cd4671988..ab398d3d2e7b 100644 --- a/integration-testing/src/flight_client_scenarios/auth_basic_proto.rs +++ b/integration-testing/src/flight_client_scenarios/auth_basic_proto.rs @@ -29,7 +29,7 @@ type Result = std::result::Result; type Client = FlightServiceClient; -pub async fn run_scenario(host: &str, port: &str) -> Result { +pub async fn run_scenario(host: &str, port: u16) -> Result { let url = format!("http://{}:{}", host, port); let mut client = FlightServiceClient::connect(url).await?; diff --git a/integration-testing/src/flight_client_scenarios/integration_test.rs b/integration-testing/src/flight_client_scenarios/integration_test.rs index bf64451e9f3d..c021020ca37b 100644 --- a/integration-testing/src/flight_client_scenarios/integration_test.rs +++ b/integration-testing/src/flight_client_scenarios/integration_test.rs @@ -38,7 +38,7 @@ type Result = std::result::Result; type Client = FlightServiceClient; -pub async fn run_scenario(host: &str, port: &str, path: &str) -> Result { +pub async fn run_scenario(host: &str, port: u16, path: &str) -> Result { let url = format!("http://{}:{}", host, port); let client = FlightServiceClient::connect(url).await?; diff --git a/integration-testing/src/flight_client_scenarios/middleware.rs b/integration-testing/src/flight_client_scenarios/middleware.rs index cbca879dca51..db8c42cc081c 100644 --- a/integration-testing/src/flight_client_scenarios/middleware.rs +++ b/integration-testing/src/flight_client_scenarios/middleware.rs @@ -24,7 +24,7 @@ use tonic::{Request, Status}; type Error = Box; type Result = std::result::Result; -pub async fn run_scenario(host: &str, port: &str) -> Result { +pub async fn run_scenario(host: &str, port: u16) -> Result { let url = format!("http://{}:{}", host, port); let conn = tonic::transport::Endpoint::new(url)?.connect().await?; let mut client = FlightServiceClient::with_interceptor(conn, middleware_interceptor); diff --git a/integration-testing/src/flight_server_scenarios.rs b/integration-testing/src/flight_server_scenarios.rs index 9163b6920860..e56252f1dfbf 100644 --- a/integration-testing/src/flight_server_scenarios.rs +++ b/integration-testing/src/flight_server_scenarios.rs @@ -27,7 +27,7 @@ pub mod middleware; type Error = Box; type Result = std::result::Result; -pub async fn listen_on(port: &str) -> Result { +pub async fn listen_on(port: u16) -> Result { let addr: SocketAddr = format!("0.0.0.0:{}", port).parse()?; let listener = TcpListener::bind(addr).await?; diff --git a/integration-testing/src/flight_server_scenarios/auth_basic_proto.rs b/integration-testing/src/flight_server_scenarios/auth_basic_proto.rs index 5607b46a9986..68a4a0d3b4ad 100644 --- a/integration-testing/src/flight_server_scenarios/auth_basic_proto.rs +++ b/integration-testing/src/flight_server_scenarios/auth_basic_proto.rs @@ -37,7 +37,7 @@ use prost::Message; use crate::{AUTH_PASSWORD, AUTH_USERNAME}; -pub async fn scenario_setup(port: &str) -> Result { +pub async fn scenario_setup(port: u16) -> Result { let service = AuthBasicProtoScenarioImpl { username: AUTH_USERNAME.into(), password: AUTH_PASSWORD.into(), diff --git a/integration-testing/src/flight_server_scenarios/integration_test.rs b/integration-testing/src/flight_server_scenarios/integration_test.rs index ae370b6f8366..9c9ebd8548f7 100644 --- a/integration-testing/src/flight_server_scenarios/integration_test.rs +++ b/integration-testing/src/flight_server_scenarios/integration_test.rs @@ -43,7 +43,7 @@ type TonicStream = Pin + Send + Sync + 'static>>; type Error = Box; type Result = std::result::Result; -pub async fn scenario_setup(port: &str) -> Result { +pub async fn scenario_setup(port: u16) -> Result { let addr = super::listen_on(port).await?; let service = FlightServiceImpl { diff --git a/integration-testing/src/flight_server_scenarios/middleware.rs b/integration-testing/src/flight_server_scenarios/middleware.rs index 1416acc4088c..5876ac9bfe6d 100644 --- a/integration-testing/src/flight_server_scenarios/middleware.rs +++ b/integration-testing/src/flight_server_scenarios/middleware.rs @@ -31,7 +31,7 @@ type TonicStream = Pin + Send + Sync + 'static>>; type Error = Box; type Result = std::result::Result; -pub async fn scenario_setup(port: &str) -> Result { +pub async fn scenario_setup(port: u16) -> Result { let service = MiddlewareScenarioImpl {}; let svc = FlightServiceServer::new(service); let addr = super::listen_on(port).await?; diff --git a/parquet/Cargo.toml b/parquet/Cargo.toml index 68925276cc17..ad68ae2f4997 100644 --- a/parquet/Cargo.toml +++ b/parquet/Cargo.toml @@ -42,7 +42,7 @@ chrono = { version = "0.4", default-features = false } num-bigint = "0.4" arrow = { path = "../arrow", version = "8.0.0", optional = true, default-features = false, features = ["ipc"] } base64 = { version = "0.13", optional = true } -clap = { version = "2.33.3", optional = true } +clap = { version = "3", optional = true, features = ["derive", "env"] } serde_json = { version = "1.0", features = ["preserve_order"], optional = true } rand = "0.8" futures = { version = "0.3", optional = true } diff --git a/parquet/src/bin/parquet-read.rs b/parquet/src/bin/parquet-read.rs index aa3b8272dadf..39e6e3bc36e8 100644 --- a/parquet/src/bin/parquet-read.rs +++ b/parquet/src/bin/parquet-read.rs @@ -21,7 +21,7 @@ //! //! `parquet-read` can be installed using `cargo`: //! ``` -//! cargo install parquet +//! cargo install parquet --features=cli //! ``` //! After this `parquet-read` should be globally available: //! ``` @@ -30,85 +30,55 @@ //! //! The binary can also be built from the source code and run as follows: //! ``` -//! cargo run --bin parquet-read XYZ.parquet +//! cargo run --features=cli --bin parquet-read XYZ.parquet //! ``` //! -//! # Usage -//! ``` -//! parquet-read [num-records] -//! ``` -//! -//! ## Flags -//! -h, --help Prints help information -//! -j, --json Print Parquet file in JSON lines Format -//! -V, --version Prints version information -//! -//! ## Args -//! Path to a Parquet file -//! Number of records to read. When not provided, all records are read. -//! //! Note that `parquet-read` reads full file schema, no projection or filtering is //! applied. extern crate parquet; -use std::{env, fs::File, path::Path}; - -use clap::{crate_authors, crate_version, App, Arg}; - +use clap::Parser; use parquet::file::reader::{FileReader, SerializedFileReader}; use parquet::record::Row; +use std::{fs::File, path::Path}; + +#[derive(Debug, Parser)] +#[clap(author, version, about("Binary file to read data from a Parquet file"), long_about = None)] +struct Args { + #[clap(short, long, help("Path to a parquet file"))] + file_name: String, + #[clap( + short, + long, + default_value_t = 0_usize, + help("Number of records to read. When not provided or 0, all records are read") + )] + num_records: usize, + #[clap(short, long, help("Print Parquet file in JSON lines format"))] + json: bool, +} fn main() { - let app = App::new("parquet-read") - .version(crate_version!()) - .author(crate_authors!()) - .about("Read data from a Parquet file and print output in console, in either built-in or JSON format") - .arg( - Arg::with_name("file_path") - .value_name("file-path") - .required(true) - .index(1) - .help("Path to a parquet file"), - ) - .arg( - Arg::with_name("num_records") - .value_name("num-records") - .index(2) - .help( - "Number of records to read. When not provided, all records are read.", - ), - ) - .arg( - Arg::with_name("json") - .short("j") - .long("json") - .takes_value(false) - .help("Print Parquet file in JSON lines format"), - ); + let args = Args::parse(); - let matches = app.get_matches(); - let filename = matches.value_of("file_path").unwrap(); - let num_records: Option = if matches.is_present("num_records") { - match matches.value_of("num_records").unwrap().parse() { - Ok(value) => Some(value), - Err(e) => panic!("Error when reading value for [num-records], {}", e), - } - } else { - None - }; + let filename = args.file_name; + let num_records = args.num_records; + let json = args.json; - let json = matches.is_present("json"); let path = Path::new(&filename); - let file = File::open(&path).unwrap(); - let parquet_reader = SerializedFileReader::new(file).unwrap(); + let file = File::open(&path).expect("Unable to open file"); + let parquet_reader = + SerializedFileReader::new(file).expect("Failed to create reader"); // Use full schema as projected schema - let mut iter = parquet_reader.get_row_iter(None).unwrap(); + let mut iter = parquet_reader + .get_row_iter(None) + .expect("Failed to create row iterator"); let mut start = 0; - let end = num_records.unwrap_or(0); - let all_records = num_records.is_none(); + let end = num_records; + let all_records = end == 0; while all_records || start < end { match iter.next() { diff --git a/parquet/src/bin/parquet-rowcount.rs b/parquet/src/bin/parquet-rowcount.rs index 3c61bab882ae..b08acd4f858e 100644 --- a/parquet/src/bin/parquet-rowcount.rs +++ b/parquet/src/bin/parquet-rowcount.rs @@ -21,7 +21,7 @@ //! //! `parquet-rowcount` can be installed using `cargo`: //! ``` -//! cargo install parquet +//! cargo install parquet --features=cli //! ``` //! After this `parquet-rowcount` should be globally available: //! ``` @@ -30,51 +30,37 @@ //! //! The binary can also be built from the source code and run as follows: //! ``` -//! cargo run --bin parquet-rowcount XYZ.parquet ABC.parquet ZXC.parquet +//! cargo run --features=cli --bin parquet-rowcount XYZ.parquet ABC.parquet ZXC.parquet //! ``` //! -//! # Usage -//! ``` -//! parquet-rowcount ... -//! ``` -//! -//! ## Flags -//! -h, --help Prints help information -//! -V, --version Prints version information -//! -//! ## Args -//! ... List of Parquet files to read from -//! //! Note that `parquet-rowcount` reads full file schema, no projection or filtering is //! applied. extern crate parquet; - -use std::{env, fs::File, path::Path}; - -use clap::{crate_authors, crate_version, App, Arg}; - +use clap::Parser; use parquet::file::reader::{FileReader, SerializedFileReader}; +use std::{fs::File, path::Path}; + +#[derive(Debug, Parser)] +#[clap(author, version, about("Binary file to return the number of rows found from Parquet file(s)"), long_about = None)] +struct Args { + #[clap( + short, + long, + multiple_values(true), + help("List of Parquet files to read from separated by space") + )] + file_paths: Vec, +} fn main() { - let matches = App::new("parquet-rowcount") - .version(crate_version!()) - .author(crate_authors!()) - .about("Return number of rows in Parquet file") - .arg( - Arg::with_name("file_paths") - .value_name("file-paths") - .required(true) - .multiple(true) - .help("List of Parquet files to read from separated by space"), - ) - .get_matches(); + let args = Args::parse(); - let filenames: Vec<&str> = matches.values_of("file_paths").unwrap().collect(); - for filename in &filenames { - let path = Path::new(filename); - let file = File::open(path).unwrap(); - let parquet_reader = SerializedFileReader::new(file).unwrap(); + for filename in args.file_paths { + let path = Path::new(&filename); + let file = File::open(path).expect("Unable to open file"); + let parquet_reader = + SerializedFileReader::new(file).expect("Unable to read file"); let row_group_metadata = parquet_reader.metadata().row_groups(); let mut total_num_rows = 0; diff --git a/parquet/src/bin/parquet-schema.rs b/parquet/src/bin/parquet-schema.rs index 1b806372b107..f1ce1b05a995 100644 --- a/parquet/src/bin/parquet-schema.rs +++ b/parquet/src/bin/parquet-schema.rs @@ -21,7 +21,7 @@ //! //! `parquet-schema` can be installed using `cargo`: //! ``` -//! cargo install parquet +//! cargo install parquet --features=cli //! ``` //! After this `parquet-schema` should be globally available: //! ``` @@ -30,63 +30,35 @@ //! //! The binary can also be built from the source code and run as follows: //! ``` -//! cargo run --bin parquet-schema XYZ.parquet +//! cargo run --features=cli --bin parquet-schema XYZ.parquet //! ``` //! -//! # Usage -//! ``` -//! parquet-schema [FLAGS] -//! ``` -//! -//! ## Flags -//! -h, --help Prints help information -//! -V, --version Prints version information -//! -v, --verbose Enable printing full file metadata -//! -//! ## Args -//! Path to a Parquet file -//! //! Note that `verbose` is an optional boolean flag that allows to print schema only, //! when not provided or print full file metadata when provided. extern crate parquet; - -use std::{env, fs::File, path::Path}; - -use clap::{crate_authors, crate_version, App, Arg}; - +use clap::Parser; use parquet::{ file::reader::{FileReader, SerializedFileReader}, schema::printer::{print_file_metadata, print_parquet_metadata}, }; +use std::{fs::File, path::Path}; -fn main() { - let matches = App::new("parquet-schema") - .version(crate_version!()) - .author(crate_authors!()) - .arg( - Arg::with_name("file_path") - .value_name("file-path") - .required(true) - .index(1) - .help("Path to a Parquet file"), - ) - .arg( - Arg::with_name("verbose") - .short("v") - .long("verbose") - .takes_value(false) - .help("Enable printing full file metadata"), - ) - .get_matches(); +#[derive(Debug, Parser)] +#[clap(author, version, about("Binary file to print the schema and metadata of a Parquet file"), long_about = None)] +struct Args { + #[clap(short, long)] + file_path: String, + #[clap(short, long, help("Enable printing full file metadata"))] + verbose: bool, +} - let filename = matches.value_of("file_path").unwrap(); +fn main() { + let args = Args::parse(); + let filename = args.file_path; let path = Path::new(&filename); - let file = match File::open(&path) { - Err(e) => panic!("Error when opening file {}: {}", path.display(), e), - Ok(f) => f, - }; - let verbose = matches.is_present("verbose"); + let file = File::open(&path).expect("Unable to open file"); + let verbose = args.verbose; match SerializedFileReader::new(file) { Err(e) => panic!("Error when parsing Parquet file: {}", e),