use std::{
fmt::{self, Debug, Display, Formatter},
path::PathBuf,
process::Command,
sync::Arc,
};
#[cfg(feature = "serde")]
use serde::{Serialize, Serializer};
use crate::error::GamesParsingError;
#[cfg(feature = "serde")]
fn serialize_debug<S, T>(x: &T, s: S) -> Result<S::Ok, S::Error>
where
T: Debug,
S: Serializer,
{
s.serialize_str(&format!("{x:?}"))
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Game {
pub title: String,
pub path_icon: Option<PathBuf>,
pub path_box_art: Option<PathBuf>,
pub path_game_dir: Option<PathBuf>,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_debug"))]
pub launch_command: Command,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_debug"))]
pub source: SupportedLaunchers,
}
#[derive(Clone, PartialEq, Eq)]
pub enum SupportedLaunchers {
Steam,
SteamShortcuts,
Lutris,
Bottles,
HeroicGamesAmazon,
HeroicGamesEpic,
HeroicGamesGOG,
HeroicGamesSideload,
MinecraftPrism,
MinecraftAT,
Itch,
}
pub type GamesResult = Result<Vec<Game>, GamesParsingError>;
impl Debug for SupportedLaunchers {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
SupportedLaunchers::Steam => "Steam",
SupportedLaunchers::SteamShortcuts => "Steam (shortcuts)",
SupportedLaunchers::HeroicGamesAmazon =>
"Heroic Games Launcher (Amazon Prime Gaming)",
SupportedLaunchers::HeroicGamesEpic => "Heroic Games Launcher (Epic Games Store)",
SupportedLaunchers::HeroicGamesGOG => "Heroic Games Launcher (GOG)",
SupportedLaunchers::HeroicGamesSideload => "Heroic Games Launcher (Sideload)",
SupportedLaunchers::Lutris => "Lutris",
SupportedLaunchers::Bottles => "Bottles",
SupportedLaunchers::MinecraftPrism => "Prism Launcher",
SupportedLaunchers::MinecraftAT => "ATLauncher",
SupportedLaunchers::Itch => "Itch",
}
)
}
}
impl Display for SupportedLaunchers {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
}
}
pub trait Launcher: Send + Debug {
fn get_launcher_type(&self) -> SupportedLaunchers;
fn is_detected(&self) -> bool;
fn get_detected_games(&self) -> GamesResult;
}
pub type Launchers = Vec<Arc<dyn Launcher>>;
pub type GamesPerLauncher = Vec<(SupportedLaunchers, Vec<Game>)>;
pub trait GamesDetector {
fn get_detected_launchers(&self) -> Launchers;
fn get_all_detected_games(&self) -> Vec<Game>;
fn get_all_detected_games_with_box_art(&self) -> Vec<Game>;
fn get_all_detected_games_per_launcher(&self) -> GamesPerLauncher;
fn get_all_detected_games_from_specific_launcher(
&self,
launcher_type: SupportedLaunchers,
) -> Option<Vec<Game>>;
}