Error handling

Before we continue, we need to quickly add some error handling to handle the case where a user forgets to add the command-line flag.

fn main() {
use std::{error, fmt};

#[derive(Debug, Clone)]
pub struct ErrorMissingSpecifier;

impl fmt::Display for ErrorMissingSpecifier {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "missing node specifier. you must specify either a or b")

impl error::Error for ErrorMissingSpecifier {}

Finally we can read the flag from the command-line by adding the following lines to main():

use crate::{

async fn main() -> Result<()> {
    let settings: Result<AppSettings> = match std::env::args().nth(1) {
        Some(id) => match id.as_str() {
            "a" => alice(),
            "b" => bob(),
            _ => Err(ErrorMissingSpecifier.into()),
        None => Err(ErrorMissingSpecifier.into()),