Skip to content

Commit b57ae64

Browse files
committed
Add lib.rs to CLI package to call CLI from other binaries
1 parent 7756063 commit b57ae64

File tree

4 files changed

+152
-132
lines changed

4 files changed

+152
-132
lines changed

splashsurf/src/cli.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//! The `splashsurf` surface reconstruction CLI.
2+
//!
3+
//! For documentation of the CLI see the [README](https://github.com/InteractiveComputerGraphics/splashsurf) in the project repository.
4+
//! The reconstruction procedure and other internals of the CLI are provided by the [`splashsurf_lib`] crate.
5+
6+
use crate::allocator::GetPeakAllocatedMemory;
7+
use crate::{convert, logging, reconstruction};
8+
use anyhow::Context;
9+
use clap::Parser;
10+
use log::info;
11+
12+
// Register allocator to track memory usage, might decrease performance if enabled
13+
crate::register_counting_allocator!(GLOBAL_ALLOCATOR, enable = false);
14+
15+
// TODO: Use different logging approach when processing multiple files in parallel
16+
// TODO: Does coarse_prof work with multiple threads?
17+
// TODO: Check if all paths supplied using the cmd args are valid
18+
// TODO: Clean up the parameter structs and conversions
19+
20+
static HELP_TEMPLATE: &str = "{before-help}{name} (v{version}) - {author-with-newline}{about-with-newline}\n{usage-heading} {usage}\n\n{all-args}{after-help}";
21+
22+
#[derive(Clone, Debug, clap::Parser)]
23+
#[command(
24+
name = "splashsurf",
25+
author = "Fabian Löschner <[email protected]>",
26+
about = "Surface reconstruction for particle data from SPH simulations (https://github.com/InteractiveComputerGraphics/splashsurf)",
27+
version,
28+
propagate_version = true,
29+
help_template = HELP_TEMPLATE,
30+
)]
31+
struct CommandlineArgs {
32+
/// Enable quiet mode (no output except for severe panic messages), overrides verbosity level
33+
#[arg(long, short = 'q', global = true)]
34+
quiet: bool,
35+
/// Print more verbose output, use multiple "v"s for even more verbose output (-v, -vv)
36+
#[arg(short, action = clap::ArgAction::Count, global = true)]
37+
verbosity: u8,
38+
/// Subcommands
39+
#[command(subcommand)]
40+
subcommand: Subcommand,
41+
}
42+
43+
#[derive(Clone, Debug, clap::Parser)]
44+
enum Subcommand {
45+
/// Reconstruct a surface from particle data
46+
#[command(help_template = HELP_TEMPLATE)]
47+
Reconstruct(reconstruction::ReconstructSubcommandArgs),
48+
/// Convert particle or mesh files between different file formats
49+
#[command(help_template = HELP_TEMPLATE)]
50+
Convert(convert::ConvertSubcommandArgs),
51+
}
52+
53+
pub fn run_splashsurf(args: &[std::ffi::OsString]) -> Result<(), anyhow::Error> {
54+
run_splashsurf_impl(args).inspect_err(logging::log_error)
55+
}
56+
57+
fn run_splashsurf_impl(args: &[std::ffi::OsString]) -> Result<(), anyhow::Error> {
58+
let cmd_args = CommandlineArgs::parse_from(args);
59+
60+
let verbosity = VerbosityLevel::from(cmd_args.verbosity);
61+
let is_quiet = cmd_args.quiet;
62+
63+
logging::initialize_logging(verbosity, is_quiet).context("Failed to initialize logging")?;
64+
logging::log_program_info();
65+
66+
// Delegate to subcommands
67+
let result = match &cmd_args.subcommand {
68+
Subcommand::Reconstruct(cmd_args) => reconstruction::reconstruct_subcommand(cmd_args),
69+
Subcommand::Convert(cmd_args) => convert::convert_subcommand(cmd_args),
70+
};
71+
72+
// Write coarse_prof stats using log::info
73+
info!("Timings:");
74+
splashsurf_lib::profiling::write_to_string()
75+
.unwrap()
76+
.split("\n")
77+
.filter(|l| !l.is_empty())
78+
.for_each(|l| info!("{}", l));
79+
80+
// Print memory stats if available
81+
if let Some(peak_allocation_bytes) = GLOBAL_ALLOCATOR.get_peak_allocated_memory() {
82+
info!(
83+
"Peak memory usage: {} bytes ({:.2}MB)",
84+
peak_allocation_bytes,
85+
peak_allocation_bytes as f64 * 1e-6
86+
);
87+
}
88+
89+
info!(
90+
"Finished at {}.",
91+
chrono::Local::now().to_rfc3339_opts(chrono::SecondsFormat::Micros, false)
92+
);
93+
94+
result
95+
}
96+
97+
#[derive(Copy, Clone, Debug)]
98+
pub(crate) enum VerbosityLevel {
99+
None,
100+
Verbose,
101+
VeryVerbose,
102+
VeryVeryVerbose,
103+
}
104+
105+
impl From<u8> for VerbosityLevel {
106+
fn from(value: u8) -> Self {
107+
match value {
108+
0 => VerbosityLevel::None,
109+
1 => VerbosityLevel::Verbose,
110+
2 => VerbosityLevel::VeryVerbose,
111+
3 => VerbosityLevel::VeryVeryVerbose,
112+
_ => VerbosityLevel::VeryVeryVerbose,
113+
}
114+
}
115+
}
116+
117+
impl VerbosityLevel {
118+
/// Maps this verbosity level to a log filter
119+
pub fn into_filter(self) -> Option<log::LevelFilter> {
120+
match self {
121+
VerbosityLevel::None => None,
122+
VerbosityLevel::Verbose => Some(log::LevelFilter::Info),
123+
VerbosityLevel::VeryVerbose => Some(log::LevelFilter::Debug),
124+
VerbosityLevel::VeryVeryVerbose => Some(log::LevelFilter::Trace),
125+
}
126+
}
127+
}

splashsurf/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub mod cli;
2+
mod convert;
3+
mod io;
4+
mod reconstruction;
5+
#[macro_use]
6+
mod allocator;
7+
mod logging;
8+
#[cfg(test)]
9+
mod tests;
10+
11+
pub(crate) use register_counting_allocator;

splashsurf/src/logging.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
use anyhow::anyhow;
21
use std::env;
32
use std::io::Write;
43

5-
use crate::VerbosityLevel;
4+
use anyhow::anyhow;
65
use fern::Output;
76
use indicatif::{ProgressBar, WeakProgressBar};
87
use log::{error, info};
98
use once_cell::sync::Lazy;
109
use parking_lot::RwLock;
1110

11+
use crate::cli::VerbosityLevel;
12+
1213
#[derive(Debug)]
1314
pub struct ProgressHandler<T: Write + Send>(T);
1415

@@ -152,7 +153,10 @@ where
152153
pub(crate) fn log_program_info() {
153154
info!(
154155
"{} v{} ({})",
155-
env!("CARGO_BIN_NAME"),
156+
//env!("CARGO_BIN_NAME"),
157+
std::env::args()
158+
.next()
159+
.unwrap_or_else(|| "splashsurf".to_string()),
156160
env!("CARGO_PKG_VERSION"),
157161
env!("CARGO_PKG_NAME")
158162
);

splashsurf/src/main.rs

Lines changed: 7 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
//! The `splashsurf` surface reconstruction CLI.
2-
//!
3-
//! For documentation of the CLI see the [README](https://github.com/InteractiveComputerGraphics/splashsurf) in the project repository.
4-
//! The reconstruction procedure and other internals of the CLI are provided by the [`splashsurf_lib`] crate.
5-
1+
pub mod cli;
62
mod convert;
73
mod io;
84
mod reconstruction;
@@ -12,52 +8,7 @@ mod logging;
128
#[cfg(test)]
139
mod tests;
1410

15-
use crate::allocator::GetPeakAllocatedMemory;
16-
use anyhow::Context;
17-
use clap::Parser;
18-
use log::info;
19-
20-
// Register allocator to track memory usage, might decrease performance if enabled
21-
register_counting_allocator!(GLOBAL_ALLOCATOR, enable = false);
22-
23-
// TODO: Use different logging approach when processing multiple files in parallel
24-
// TODO: Add start and end index for input file sequences
25-
// TODO: Does coarse_prof work with multiple threads?
26-
// TODO: Check if all paths supplied using the cmd args are valid
27-
// TODO: Clean up the parameter structs and conversions
28-
29-
static HELP_TEMPLATE: &str = "{before-help}{name} (v{version}) - {author-with-newline}{about-with-newline}\n{usage-heading} {usage}\n\n{all-args}{after-help}";
30-
31-
#[derive(Clone, Debug, clap::Parser)]
32-
#[command(
33-
name = "splashsurf",
34-
author = "Fabian Löschner <[email protected]>",
35-
about = "Surface reconstruction for particle data from SPH simulations (https://github.com/InteractiveComputerGraphics/splashsurf)",
36-
version,
37-
propagate_version = true,
38-
help_template = HELP_TEMPLATE,
39-
)]
40-
struct CommandlineArgs {
41-
/// Enable quiet mode (no output except for severe panic messages), overrides verbosity level
42-
#[arg(long, short = 'q', global = true)]
43-
quiet: bool,
44-
/// Print more verbose output, use multiple "v"s for even more verbose output (-v, -vv)
45-
#[arg(short, action = clap::ArgAction::Count, global = true)]
46-
verbosity: u8,
47-
/// Subcommands
48-
#[command(subcommand)]
49-
subcommand: Subcommand,
50-
}
51-
52-
#[derive(Clone, Debug, clap::Parser)]
53-
enum Subcommand {
54-
/// Reconstruct a surface from particle data
55-
#[command(help_template = HELP_TEMPLATE)]
56-
Reconstruct(reconstruction::ReconstructSubcommandArgs),
57-
/// Convert particle or mesh files between different file formats
58-
#[command(help_template = HELP_TEMPLATE)]
59-
Convert(convert::ConvertSubcommandArgs),
60-
}
11+
pub(crate) use register_counting_allocator;
6112

6213
fn main() -> Result<(), anyhow::Error> {
6314
/*
@@ -68,83 +19,10 @@ fn main() -> Result<(), anyhow::Error> {
6819
}));
6920
*/
7021

71-
std::process::exit(match run_splashsurf() {
72-
Ok(_) => 0,
73-
Err(err) => {
74-
logging::log_error(&err);
75-
1
76-
}
77-
});
78-
}
79-
80-
fn run_splashsurf() -> Result<(), anyhow::Error> {
81-
let cmd_args = CommandlineArgs::parse();
82-
83-
let verbosity = VerbosityLevel::from(cmd_args.verbosity);
84-
let is_quiet = cmd_args.quiet;
85-
86-
logging::initialize_logging(verbosity, is_quiet).context("Failed to initialize logging")?;
87-
logging::log_program_info();
88-
89-
// Delegate to subcommands
90-
let result = match &cmd_args.subcommand {
91-
Subcommand::Reconstruct(cmd_args) => reconstruction::reconstruct_subcommand(cmd_args),
92-
Subcommand::Convert(cmd_args) => convert::convert_subcommand(cmd_args),
93-
};
94-
95-
// Write coarse_prof stats using log::info
96-
info!("Timings:");
97-
splashsurf_lib::profiling::write_to_string()
98-
.unwrap()
99-
.split("\n")
100-
.filter(|l| !l.is_empty())
101-
.for_each(|l| info!("{}", l));
102-
103-
// Print memory stats if available
104-
if let Some(peak_allocation_bytes) = GLOBAL_ALLOCATOR.get_peak_allocated_memory() {
105-
info!(
106-
"Peak memory usage: {} bytes ({:.2}MB)",
107-
peak_allocation_bytes,
108-
peak_allocation_bytes as f64 * 1e-6
109-
);
110-
}
111-
112-
info!(
113-
"Finished at {}.",
114-
chrono::Local::now().to_rfc3339_opts(chrono::SecondsFormat::Micros, false)
22+
std::process::exit(
23+
match cli::run_splashsurf(std::env::args_os().collect::<Vec<_>>().as_slice()) {
24+
Ok(_) => 0,
25+
Err(_) => 1,
26+
},
11527
);
116-
117-
result
118-
}
119-
120-
#[derive(Copy, Clone, Debug)]
121-
enum VerbosityLevel {
122-
None,
123-
Verbose,
124-
VeryVerbose,
125-
VeryVeryVerbose,
126-
}
127-
128-
impl From<u8> for VerbosityLevel {
129-
fn from(value: u8) -> Self {
130-
match value {
131-
0 => VerbosityLevel::None,
132-
1 => VerbosityLevel::Verbose,
133-
2 => VerbosityLevel::VeryVerbose,
134-
3 => VerbosityLevel::VeryVeryVerbose,
135-
_ => VerbosityLevel::VeryVeryVerbose,
136-
}
137-
}
138-
}
139-
140-
impl VerbosityLevel {
141-
/// Maps this verbosity level to a log filter
142-
fn into_filter(self) -> Option<log::LevelFilter> {
143-
match self {
144-
VerbosityLevel::None => None,
145-
VerbosityLevel::Verbose => Some(log::LevelFilter::Info),
146-
VerbosityLevel::VeryVerbose => Some(log::LevelFilter::Debug),
147-
VerbosityLevel::VeryVeryVerbose => Some(log::LevelFilter::Trace),
148-
}
149-
}
15028
}

0 commit comments

Comments
 (0)