Skip to content

Commit

Permalink
Generate completion & manpage (#357)
Browse files Browse the repository at this point in the history
* Generate completion & manpage

* Write changelog
  • Loading branch information
cyqsimon authored Jan 27, 2024
1 parent 592f733 commit dc0468c
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

## [0.22.2] - 2024-01-28

## Added

* Generate completion & manpage #357 - @cyqsimon

## [0.22.1] - 2024-01-28

## Fixed
Expand Down
27 changes: 27 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,15 @@ pnet_base = "0.34.0"
regex = "1.10.3"
rstest = "0.18.2"

[target.'cfg(target_os = "windows")'.build-dependencies]
[build-dependencies]
anyhow = "1.0.79"
clap = { version = "4.4.18", features = ["derive"] }
clap-verbosity-flag = "2.1.2"
clap_complete = "4.4.9"
clap_mangen = "0.2.17"
derivative = "2.2.0"
strum = { version = "0.25.0", features = ["derive"] }

[target.'cfg(target_os = "windows")'.build-dependencies]
http_req = "0.10.2"
zip = "0.6.6"
33 changes: 33 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
use std::{env, fs::File};

use anyhow::anyhow;
use clap::CommandFactory;
use clap_complete::Shell;
use clap_mangen::Man;

fn main() {
build_completion_manpage().unwrap();

#[cfg(target_os = "windows")]
download_windows_npcap_sdk().unwrap();
}

include!("src/cli.rs");

fn build_completion_manpage() -> anyhow::Result<()> {
let mut cmd = Opt::command();

// build into `BANDWHICH_GEN_DIR` with a fallback to `OUT_DIR`
let gen_dir: PathBuf = env::var_os("BANDWHICH_GEN_DIR")
.or_else(|| env::var_os("OUT_DIR"))
.ok_or(anyhow!("OUT_DIR is unset"))?
.into();

// completion
for &shell in Shell::value_variants() {
clap_complete::generate_to(shell, &mut cmd, "bandwhich", &gen_dir)?;
}

// manpage
let mut manpage_out = File::create(gen_dir.join("bandwhich.1"))?;
let manpage = Man::new(cmd);
manpage.render(&mut manpage_out)?;

Ok(())
}

#[cfg(target_os = "windows")]
fn download_windows_npcap_sdk() -> anyhow::Result<()> {
use std::{
Expand Down
24 changes: 19 additions & 5 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::{net::Ipv4Addr, path::PathBuf};

use clap::{Args, Parser};
use clap::{Args, Parser, ValueEnum, ValueHint};
use clap_verbosity_flag::{InfoLevel, Verbosity};
use derivative::Derivative;

use crate::display::BandwidthUnitFamily;
use strum::EnumIter;

#[derive(Clone, Debug, Derivative, Parser)]
#[derivative(Default)]
Expand All @@ -30,7 +29,7 @@ pub struct Opt {
/// A dns server ip to use instead of the system default
pub dns_server: Option<Ipv4Addr>,

#[arg(long)]
#[arg(long, value_hint = ValueHint::FilePath)]
/// Enable debug logging to a file
pub log_to: Option<PathBuf>,

Expand Down Expand Up @@ -58,9 +57,24 @@ pub struct RenderOpts {

#[arg(short, long, value_enum, default_value_t)]
/// Choose a specific family of units
pub unit_family: BandwidthUnitFamily,
pub unit_family: UnitFamily,

#[arg(short, long)]
/// Show total (cumulative) usages
pub total_utilization: bool,
}

// IMPRV: it would be nice if we can `#[cfg_attr(not(build), derive(strum::EnumIter))]` this
// unfortunately there is no configuration option for build script detection
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, ValueEnum, EnumIter)]
pub enum UnitFamily {
#[default]
/// bytes, in powers of 2^10
BinBytes,
/// bits, in powers of 2^10
BinBits,
/// bytes, in powers of 10^3
SiBytes,
/// bits, in powers of 10^3
SiBits,
}
33 changes: 16 additions & 17 deletions src/display/components/display_bandwidth.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::fmt;

use clap::ValueEnum;
use strum::EnumIter;
use derivative::Derivative;

use crate::cli::UnitFamily;

#[derive(Copy, Clone, Debug)]
pub struct DisplayBandwidth {
Expand All @@ -16,17 +17,14 @@ impl fmt::Display for DisplayBandwidth {
}
}

#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, ValueEnum, EnumIter)]
pub enum BandwidthUnitFamily {
#[default]
/// bytes, in powers of 2^10
BinBytes,
/// bits, in powers of 2^10
BinBits,
/// bytes, in powers of 10^3
SiBytes,
/// bits, in powers of 10^3
SiBits,
/// Type wrapper around [`UnitFamily`] to provide extra functionality.
#[derive(Copy, Clone, Derivative, Default, Eq, PartialEq)]
#[derivative(Debug = "transparent")]
pub struct BandwidthUnitFamily(UnitFamily);
impl From<UnitFamily> for BandwidthUnitFamily {
fn from(value: UnitFamily) -> Self {
Self(value)
}
}
impl BandwidthUnitFamily {
#[inline]
Expand All @@ -39,9 +37,9 @@ impl BandwidthUnitFamily {
/// Binary base: 2^10.
const BB: f64 = 1024.0;

use BandwidthUnitFamily as F;
use UnitFamily as F;
// probably could macro this stuff, but I'm too lazy
match self {
match self.0 {
F::BinBytes => [
(1.0, BB * STEP_UP_FRAC, "B"),
(BB, BB.powi(2) * STEP_UP_FRAC, "KiB"),
Expand Down Expand Up @@ -99,11 +97,12 @@ mod tests {
use itertools::Itertools;
use strum::IntoEnumIterator;

use crate::display::{BandwidthUnitFamily, DisplayBandwidth};
use crate::{cli::UnitFamily, display::DisplayBandwidth};

#[test]
fn bandwidth_formatting() {
let test_bandwidths_formatted = BandwidthUnitFamily::iter()
let test_bandwidths_formatted = UnitFamily::iter()
.map_into()
.cartesian_product(
// I feel like this is a decent selection of values
(-6..60)
Expand Down
2 changes: 1 addition & 1 deletion src/display/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ where
let state = {
let mut state = UIState::default();
state.interface_name = opts.interface.clone();
state.unit_family = opts.render_opts.unit_family;
state.unit_family = opts.render_opts.unit_family.into();
state.cumulative_mode = opts.render_opts.total_utilization;
state
};
Expand Down

0 comments on commit dc0468c

Please sign in to comment.