use std::{
error::Error,
fmt::{Display, Formatter, Result as FmtResult},
};
pub use rosu_map::section::general::GameMode;
use crate::{Difficulty, any::CalculateError};
use super::beatmap::Beatmap;
pub trait IGameMode: Sized {
type DifficultyAttributes;
type Strains;
type Performance<'map>;
type HitResults;
type GradualDifficulty;
type GradualPerformance;
fn difficulty(
difficulty: &Difficulty,
map: &Beatmap,
) -> Result<Self::DifficultyAttributes, ConvertError>;
fn checked_difficulty(
difficulty: &Difficulty,
map: &Beatmap,
) -> Result<Self::DifficultyAttributes, CalculateError>;
fn strains(difficulty: &Difficulty, map: &Beatmap) -> Result<Self::Strains, ConvertError>;
fn performance(map: &Beatmap) -> Self::Performance<'_>;
fn gradual_difficulty(
difficulty: Difficulty,
map: &Beatmap,
) -> Result<Self::GradualDifficulty, ConvertError>;
fn gradual_performance(
difficulty: Difficulty,
map: &Beatmap,
) -> Result<Self::GradualPerformance, ConvertError>;
}
#[derive(Copy, Clone, Debug)]
pub enum ConvertError {
AlreadyConverted,
Convert { from: GameMode, to: GameMode },
}
impl Error for ConvertError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
impl Display for ConvertError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
ConvertError::AlreadyConverted => {
f.write_str("Cannot convert an already converted map")
}
ConvertError::Convert { from, to } => {
write!(f, "Cannot convert from {from:?} to {to:?}")
}
}
}
}