Integrate with clap for CLI argument parsing
This commit is contained in:
parent
efc7588c09
commit
637884cdbf
165
Cargo.lock
generated
165
Cargo.lock
generated
@ -12,6 +12,41 @@ version = "1.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "822d7d63e0c0260a050f6b1f0d316f5c79b9eab830aca526ed904e1011bd64ca"
|
checksum = "822d7d63e0c0260a050f6b1f0d316f5c79b9eab830aca526ed904e1011bd64ca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "3.0.0-beta.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"clap_derive",
|
||||||
|
"indexmap",
|
||||||
|
"lazy_static",
|
||||||
|
"os_str_bytes",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "3.0.0-beta.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gmp-mpfr-sys"
|
name = "gmp-mpfr-sys"
|
||||||
version = "1.4.5"
|
version = "1.4.5"
|
||||||
@ -22,6 +57,37 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.95"
|
version = "0.2.95"
|
||||||
@ -41,10 +107,59 @@ dependencies = [
|
|||||||
name = "opentally"
|
name = "opentally"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rug",
|
"rug",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_str_bytes"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rug"
|
name = "rug"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
@ -56,6 +171,56 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -11,3 +11,8 @@ num-traits = "0.2"
|
|||||||
version = "1.12"
|
version = "1.12"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["integer", "rational", "float"]
|
features = ["integer", "rational", "float"]
|
||||||
|
|
||||||
|
[dependencies.clap]
|
||||||
|
version = "3.0.0-beta.2"
|
||||||
|
default-features = false
|
||||||
|
features = ["std", "derive"]
|
||||||
|
53
src/main.rs
53
src/main.rs
@ -22,13 +22,33 @@ mod stv;
|
|||||||
use crate::election::{CandidateState, CountState, CountStateOrRef, Election, StageResult};
|
use crate::election::{CandidateState, CountState, CountStateOrRef, Election, StageResult};
|
||||||
use crate::numbers::{Number, NumType};
|
use crate::numbers::{Number, NumType};
|
||||||
|
|
||||||
use std::env;
|
use clap::Clap;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, BufRead};
|
use std::io::{self, BufRead};
|
||||||
|
|
||||||
const DECIMAL_PLACES: usize = 0;
|
#[derive(Clap)]
|
||||||
|
struct Opts {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
command: Command,
|
||||||
|
}
|
||||||
|
|
||||||
fn print_stage<N: Number>(stage_num: usize, result: &StageResult<N>) {
|
#[derive(Clap)]
|
||||||
|
enum Command {
|
||||||
|
STV(STV),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Count a single transferable vote (STV) election
|
||||||
|
#[derive(Clap)]
|
||||||
|
struct STV {
|
||||||
|
/// Path to the BLT file to be counted
|
||||||
|
filename: String,
|
||||||
|
/// Print votes to specified decimal places in results report
|
||||||
|
#[clap(long, default_value="2")]
|
||||||
|
pp_decimals: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_stage<N: Number>(stage_num: usize, result: &StageResult<N>, cmd_opts: &STV) {
|
||||||
println!("{}. {}", stage_num, result.title);
|
println!("{}. {}", stage_num, result.title);
|
||||||
println!("{}", result.logs.join(" "));
|
println!("{}", result.logs.join(" "));
|
||||||
|
|
||||||
@ -41,27 +61,28 @@ fn print_stage<N: Number>(stage_num: usize, result: &StageResult<N>) {
|
|||||||
//for (candidate, count_card) in candidates.into_iter().rev() {
|
//for (candidate, count_card) in candidates.into_iter().rev() {
|
||||||
for (candidate, count_card) in candidates {
|
for (candidate, count_card) in candidates {
|
||||||
if count_card.state == CandidateState::ELECTED {
|
if count_card.state == CandidateState::ELECTED {
|
||||||
println!("- {}: {:.dps$} ({:.dps$}) - ELECTED {}", candidate.name, count_card.votes, count_card.transfers, count_card.order_elected, dps=DECIMAL_PLACES);
|
println!("- {}: {:.dps$} ({:.dps$}) - ELECTED {}", candidate.name, count_card.votes, count_card.transfers, count_card.order_elected, dps=cmd_opts.pp_decimals);
|
||||||
} else if count_card.state == CandidateState::EXCLUDED {
|
} else if count_card.state == CandidateState::EXCLUDED {
|
||||||
println!("- {}: {:.dps$} ({:.dps$}) - Excluded {}", candidate.name, count_card.votes, count_card.transfers, -count_card.order_elected, dps=DECIMAL_PLACES);
|
println!("- {}: {:.dps$} ({:.dps$}) - Excluded {}", candidate.name, count_card.votes, count_card.transfers, -count_card.order_elected, dps=cmd_opts.pp_decimals);
|
||||||
} else {
|
} else {
|
||||||
println!("- {}: {:.dps$} ({:.dps$})", candidate.name, count_card.votes, count_card.transfers, dps=DECIMAL_PLACES);
|
println!("- {}: {:.dps$} ({:.dps$})", candidate.name, count_card.votes, count_card.transfers, dps=cmd_opts.pp_decimals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Quota: {:.dps$}", result.state.as_ref().quota, dps=DECIMAL_PLACES);
|
println!("Quota: {:.dps$}", result.state.as_ref().quota, dps=cmd_opts.pp_decimals);
|
||||||
|
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Read arguments
|
|
||||||
let file_name = env::args().skip(1).next().expect("First argument must be path to BLT file");
|
|
||||||
|
|
||||||
let should_clone_state = false;
|
let should_clone_state = false;
|
||||||
|
|
||||||
|
// Read arguments
|
||||||
|
let opts: Opts = Opts::parse();
|
||||||
|
let Command::STV(cmd_opts) = opts.command;
|
||||||
|
|
||||||
// Read BLT file
|
// Read BLT file
|
||||||
let file = File::open(file_name).expect("IO Error");
|
let file = File::open(&cmd_opts.filename).expect("IO Error");
|
||||||
let lines = io::BufReader::new(file).lines();
|
let lines = io::BufReader::new(file).lines();
|
||||||
let election: Election<NumType> = Election::from_blt(lines);
|
let election: Election<NumType> = Election::from_blt(lines);
|
||||||
|
|
||||||
@ -80,7 +101,7 @@ fn main() {
|
|||||||
logs: vec!["First preferences distributed."],
|
logs: vec!["First preferences distributed."],
|
||||||
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
||||||
};
|
};
|
||||||
print_stage(1, &result);
|
print_stage(1, &result, &cmd_opts);
|
||||||
|
|
||||||
let mut stage_num = 1;
|
let mut stage_num = 1;
|
||||||
|
|
||||||
@ -101,7 +122,7 @@ fn main() {
|
|||||||
logs: vec!["Continuing exclusion."],
|
logs: vec!["Continuing exclusion."],
|
||||||
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
||||||
};
|
};
|
||||||
print_stage(stage_num, &result);
|
print_stage(stage_num, &result, &cmd_opts);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +134,7 @@ fn main() {
|
|||||||
logs: vec!["Surplus distributed."],
|
logs: vec!["Surplus distributed."],
|
||||||
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
||||||
};
|
};
|
||||||
print_stage(stage_num, &result);
|
print_stage(stage_num, &result, &cmd_opts);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +146,7 @@ fn main() {
|
|||||||
logs: vec!["Bulk election."],
|
logs: vec!["Bulk election."],
|
||||||
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
||||||
};
|
};
|
||||||
print_stage(stage_num, &result);
|
print_stage(stage_num, &result, &cmd_opts);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +158,7 @@ fn main() {
|
|||||||
logs: vec!["Candidate excluded."],
|
logs: vec!["Candidate excluded."],
|
||||||
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
state: if should_clone_state { CountStateOrRef::State(state.clone()) } else { CountStateOrRef::Ref(&state) },
|
||||||
};
|
};
|
||||||
print_stage(stage_num, &result);
|
print_stage(stage_num, &result, &cmd_opts);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user