You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: launcher.rs
    path of file: ./repos/gpg-tui/src/app
    
    the code of the file until where you have to start completion: use crate::app::command::Command;
use crate::app::keys::{KeyBinding, KEY_BINDINGS};
use crate::app::mode::Mode;
use crate::app::prompt::{OutputType, Prompt, COMMAND_PREFIX, SEARCH_PREFIX};
use crate::app::selection::Selection;
use crate::app::splash::{SplashConfig, SplashScreen};
use crate::app::state::State;
use crate::app::style::Style;
use crate::app::tab::Tab;
use crate::args::Args;
use crate::gpg::context::GpgContext;
use crate::gpg::key::{GpgKey, KeyDetail, KeyType};
use crate::widget::list::StatefulList;
use crate::widget::row::ScrollDirection;
use crate::widget::style::Color as WidgetColor;
use crate::widget::table::{StatefulTable, TableSize, TableState};
use anyhow::{Error as AnyhowError, Result};
use clap::ValueEnum;
use colorsys::Rgb;
use copypasta_ext::display::DisplayServer as ClipboardDisplayServer;
use copypasta_ext::ClipboardProviderExt;
use ratatui::style::Color;
use std::collections::HashMap;
use std::path::Path;
use std::process::Command as OsCommand;
use std::str;
use std::str::FromStr;
use std::time::Instant;

/// Max duration of prompt messages.
const MESSAGE_DURATION: u128 = 1750;

/// Splash screen config.
static SPLASH_CONFIG: SplashConfig = SplashConfig {
	image_path: "splash.jpg",
	sha256_hash: Some(hex_literal::hex!(
		"dffd680d649a4a4b5df25dc1afaa
    
	fn test_app_launcher() -> Result<()> {
		let args = Args::default();
		let config = GpgConfig::new(&args)?;
		let mut context = GpgContext::new(config)?;
		let mut app = App::new(&mut context, &args)?;
		app.run_command(Command::Refresh)?;

		app.run_command(Command::ShowHelp)?;
		assert_eq!(Tab::Help, app.tab);
		app.run_command(Command::ShowOptions)?;
		assert!(app.state.show_options);

		app.run_command(Command::ChangeStyle(Style::Colored))?;
		assert_eq!(Style::Colored, app.state.style);
		app.run_command(Command::ChangeStyle(Style::Plain))?;
		assert_eq!(Style::Plain, app.state.style);

		app.run_command(Command::ListKeys(KeyType::Public))?;
		app.run_command(Command::ToggleDetail(false))?;
		let mut detail = app.state.detail_level;
		detail.increase();
		app.run_command(Command::ToggleDetail(true))?;
		assert_eq!(detail, app.state.detail_level);

		let prompt_text = format!("{COMMAND_PREFIX}test");
		app.run_command(Command::Set(
			String::from("prompt"),
			prompt_text.to_string(),
		))?;
		assert_eq!(prompt_text, app.prompt.text);

		let home_dir = dirs_next::home_dir()
			.expect("home directory not found")
			.to_str()
			.expect("invalid chars in home directory")
			.to_string();
		app.run_command(Command::Set(
			String::from("output"),
			home_dir.to_string(),
		))?;
		app.run_command(Command::Get(String::from("output")))?;
		assert!(app.prompt.text.contains(&home_dir));

		let mut test_values = vec![
			("output", "/tmp"),
			("mode", "normal"),
			("armor", "true"),
			("signer", "0x0"),
			("minimize", "10"),
			("margin", "2"),
			("style", "plain"),
			("color", "#123123"),
		];
		if cfg!(feature = "gpg-tests") {
			test_values.push(("detail", "full"));
		}
		for (option, value) in test_values {
			app.run_command(Command::Set(
				option.to_string(),
				value.to_string(),
			))?;
			app.run_command(Command::Get(option.to_string()))?;
			assert!(
				(app.prompt.text == format!("{option}: {value}"))
					|| app.prompt.text.contains(value)
			);
		}

		app.mode = Mode::Normal;
		app.run_command(Command::SwitchMode(Mode::Visual))?;
		assert_eq!(Mode::Visual, app.mode);

		app.run_command(Command::EnableInput)?;
		assert!(app.prompt.is_command_input_enabled());
		assert_eq!(COMMAND_PREFIX.to_string(), app.prompt.text);

		app.run_command(Command::Search(Some(String::from("x"))))?;
		assert!(app.prompt.is_search_enabled());
		assert_eq!(format!("{SEARCH_PREFIX}x"), app.prompt.text);

		app.tab = Tab::Keys(KeyType::Public);
		app.run_command(Command::NextTab)?;
		assert_eq!(Tab::Keys(KeyType::Secret), app.tab);
		app.run_command(Command::NextTab)?;
		assert_eq!(Tab::Keys(KeyType::Public), app.tab);

		app.tick();
		app.run_command(Command::ShowOutput(
			OutputType::Success,
			String::from("test"),
		))?;
		assert_eq!("test", app.prompt.text);
		thread::sleep(Duration::from_millis(
			(MESSAGE_DURATION + 10).try_into()?,
		));
		app.tick();
		assert_eq!("", app.prompt.text);

		app.run_command(Command::Quit)?;
		assert!(!app.state.running);

		app.run_command(Command::None)
	}