use super::super::Guid;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RecipeKind {
BuildingBlock,
Roof,
Overgrowth,
Terrain,
Other,
}
impl RecipeKind {
pub const ALL: &[Self] = &[
Self::Other,
Self::BuildingBlock,
Self::Roof,
Self::Overgrowth,
Self::Terrain,
];
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::BuildingBlock => "building-block",
Self::Roof => "roof",
Self::Overgrowth => "overgrowth",
Self::Terrain => "terrain",
Self::Other => "other",
}
}
#[must_use]
pub fn named(name: &str) -> Option<Self> {
Self::ALL.iter().copied().find(|kind| kind.name() == name)
}
#[must_use]
pub const fn code(self) -> crate::abi::RecipeKind {
use crate::abi::RecipeKind as Abi;
match self {
Self::BuildingBlock => Abi::BUILDING_BLOCK,
Self::Roof => Abi::ROOF,
Self::Overgrowth => Abi::OVERGROWTH,
Self::Terrain => Abi::TERRAIN,
Self::Other => Abi::OTHER,
}
}
pub(super) fn of(item: Guid) -> Option<Self> {
let host = crate::host()?;
let mut out = crate::abi::RecipeKind::OTHER;
(host.api().recipe_kind)(host.handle(), item.id(), &raw mut out)
.is_ok()
.then(|| out.into())
}
}
impl From<crate::abi::RecipeKind> for RecipeKind {
fn from(kind: crate::abi::RecipeKind) -> Self {
use crate::abi::RecipeKind as Abi;
match kind {
Abi::BUILDING_BLOCK => Self::BuildingBlock,
Abi::ROOF => Self::Roof,
Abi::OVERGROWTH => Self::Overgrowth,
Abi::TERRAIN => Self::Terrain,
_ => Self::Other,
}
}
}
impl From<RecipeKind> for crate::abi::RecipeKind {
fn from(kind: RecipeKind) -> Self {
kind.code()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_kind_reads_back_from_its_name() {
for kind in RecipeKind::ALL {
assert_eq!(RecipeKind::named(kind.name()), Some(*kind));
}
assert_eq!(RecipeKind::named("Roof"), None);
}
}