aboutsummaryrefslogtreecommitdiff
path: root/nitrocli/src/main.rs
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-01-05 21:41:22 -0800
committerDaniel Mueller <deso@posteo.net>2019-01-05 21:41:22 -0800
commit6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e (patch)
tree843fb189a543e6bc95ff9e5498f5ca2d09bc67a0 /nitrocli/src/main.rs
parentb750c4b13272908a51b85072008554c344b25016 (diff)
downloadnitrocli-6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e.tar.gz
nitrocli-6d07a0c9d9a9b39247a9727dea2d90eba4e1fe9e.tar.bz2
Supply customizable stdio channels to argparse
In order to properly test the program we need to have a way to intercept data printed to the stdio channels. There are different ways to accomplish that task. While it is reasonably easy to just start the program as a dedicated process doing so properly may be problematic from inside a test because either the path to the binary has to be retrieved or cargo -- the entity which knows the path -- be invoked. None of these approaches is very appealing from a testing and code complexity point of view: an additional fork means additional sources of errors and flakiness, executing cargo has the potential to even cause rebuilds of parts of the program, and while we are already testing against a slow I/O device this additional code running is unlikely to go unnoticed in the long-term. Lastly, doing so also means that we leave Rust's type safety behind when dealing with errors that could be nicely match'ed on when the test invocation is just a function call. To avoid all this complexity we instead strive for basically just running the main function. This patch marks a first step towards achieving this goal. It introduces the infrastructure to supply custom Write objects to the argument parsing functionality. Once more we piggy-back on the command execution context and add objects representing stdout and stderr to it. We further ensure that this context is passed to the argument parser invocations.
Diffstat (limited to 'nitrocli/src/main.rs')
-rw-r--r--nitrocli/src/main.rs25
1 files changed, 20 insertions, 5 deletions
diff --git a/nitrocli/src/main.rs b/nitrocli/src/main.rs
index 4f39fdb..ad79c6e 100644
--- a/nitrocli/src/main.rs
+++ b/nitrocli/src/main.rs
@@ -1,7 +1,7 @@
// main.rs
// *************************************************************************
-// * Copyright (C) 2017-2018 Daniel Mueller (deso@posteo.net) *
+// * Copyright (C) 2017-2019 Daniel Mueller (deso@posteo.net) *
// * *
// * This program is free software: you can redistribute it and/or modify *
// * it under the terms of the GNU General Public License as published by *
@@ -73,6 +73,8 @@ mod commands;
mod error;
mod pinentry;
+use std::env;
+use std::io;
use std::process;
use std::result;
@@ -80,9 +82,16 @@ use crate::error::Error;
type Result<T> = result::Result<T, Error>;
-fn run() -> i32 {
- let args = std::env::args().collect();
- match args::handle_arguments(args) {
+/// The context used when running the program.
+pub(crate) struct RunCtx<'io> {
+ /// The `Write` object used as standard output throughout the program.
+ pub stdout: &'io mut dyn io::Write,
+ /// The `Write` object used as standard error throughout the program.
+ pub stderr: &'io mut dyn io::Write,
+}
+
+fn run<'ctx, 'io: 'ctx>(ctx: &'ctx mut RunCtx<'io>, args: Vec<String>) -> i32 {
+ match args::handle_arguments(ctx, args) {
Ok(()) => 0,
Err(err) => match err {
Error::ArgparseError(err) => match err {
@@ -100,5 +109,11 @@ fn run() -> i32 {
}
fn main() {
- process::exit(run());
+ let args = env::args().collect::<Vec<_>>();
+ let ctx = &mut RunCtx {
+ stdout: &mut io::stdout(),
+ stderr: &mut io::stderr(),
+ };
+
+ process::exit(run(ctx, args));
}