Repository: casey/just
File: src/config.rs (Rust)

Code before:
        arguments: positional.arguments,
        overrides,
      }
    };

    let shell_args = if matches.is_present(arg::SHELL_ARG) {
      matches
        .values_of(arg::SHELL_ARG)
        .unwrap()
        .map(str::to_owned)
        .collect()
    } else {
      Vec::new()
    };

    let shell_present = matches.occurrences_of(arg::SHELL) > 0;

    let shell_args_present = matches.occurrences_of(arg::CLEAR_SHELL_ARGS) > 0
      || matches.occurrences_of(arg::SHELL_ARG) > 0;

    Ok(Self {
      check: matches.is_present(arg::CHECK),
      dry_run: matches.is_present(arg::DRY_RUN),
      dump_format: Self::dump_format_from_matches(matches)?,
      highlight: !matches.is_present(arg::NO_HIGHLIGHT),
      shell: matches.value_of(arg::SHELL).unwrap_or("").to_owned(),
      load_dotenv: !matches.is_present(arg::NO_DOTENV),
      shell_command: matches.is_present(arg::SHELL_COMMAND),
      unsorted: matches.is_present(arg::UNSORTED),
      unstable: matches.is_present(arg::UNSTABLE),
      list_heading: matches
        .value_of(arg::LIST_HEADING)
        .unwrap_or("Available recipes:\n")
        .to_owned(),
      list_prefix: matches
        .value_of(arg::LIST_PREFIX)
        .unwrap_or("    ")
        .to_owned(),
      color,
      invocation_directory,
      search_config,
      shell_args,
      shell_present,
      shell_args_present,
      subcommand,
      dotenv_filename: matches.value_of(arg::DOTENV_FILENAME).map(str::to_owned),
      dotenv_path: matches.value_of(arg::DOTENV_PATH).map(PathBuf::from),
      verbosity,
    })
  }


Review comment (suggestion):
`""` shouldn't be used to indicated that the argument isn't present, since the user could actually pass the empty string as the argument. We should use an `Option` for the `shell` field.

Code after:
      }
    };

    let shell_args = if matches.occurrences_of(arg::SHELL_ARG) > 0
      || matches.occurrences_of(arg::CLEAR_SHELL_ARGS) > 0
    {
      Some(
        matches
          .values_of(arg::SHELL_ARG)
          .map_or(Vec::new(), |shell_args| {
            shell_args.map(str::to_owned).collect()
          }),
      )
    } else {
      None
    };

    Ok(Self {
      check: matches.is_present(arg::CHECK),
      dry_run: matches.is_present(arg::DRY_RUN),
      dump_format: Self::dump_format_from_matches(matches)?,
      highlight: !matches.is_present(arg::NO_HIGHLIGHT),
      shell: matches.value_of(arg::SHELL).map(str::to_owned),
      load_dotenv: !matches.is_present(arg::NO_DOTENV),
      shell_command: matches.is_present(arg::SHELL_COMMAND),
      unsorted: matches.is_present(arg::UNSORTED),
      unstable: matches.is_present(arg::UNSTABLE),
      list_heading: matches
        .value_of(arg::LIST_HEADING)
        .unwrap_or("Available recipes:\n")
        .to_owned(),
      list_prefix: matches
        .value_of(arg::LIST_PREFIX)
        .unwrap_or("    ")
        .to_owned(),
      color,
      invocation_directory,
      search_config,
      shell_args,
      subcommand,
      dotenv_filename: matches.value_of(arg::DOTENV_FILENAME).map(str::to_owned),
      dotenv_path: matches.value_of(arg::DOTENV_PATH).map(PathBuf::from),
      verbosity,
    })
  }

  pub(crate) fn require_unstable(&self, message: &str) -> Result<(), Error<'static>> {
    if self.unstable {
      Ok(())
    } else {
      Err(Error::Unstable {