use crate::Off;
use super::super::{DebugName, Guid, Id};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Name<'a> {
Guid(Guid),
Content(Id),
Debug(DebugName<'a>),
}
impl From<Guid> for Name<'_> {
fn from(guid: Guid) -> Self {
Self::Guid(guid)
}
}
impl From<Id> for Name<'_> {
fn from(id: Id) -> Self {
Self::Content(id)
}
}
impl<'a> From<DebugName<'a>> for Name<'a> {
fn from(name: DebugName<'a>) -> Self {
Self::Debug(name)
}
}
impl Name<'_> {
fn text(self) -> std::borrow::Cow<'static, str> {
match self {
Self::Guid(guid) => guid.to_string().into(),
Self::Content(id) => id.name().into(),
Self::Debug(name) => name.0.to_owned().into(),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RecipeRule<'a> {
Recipe(Name<'a>),
Output(Name<'a>),
Workshop(Name<'a>),
Hand,
}
impl<'a> RecipeRule<'a> {
#[must_use]
pub fn recipe(name: impl Into<Name<'a>>) -> Self {
Self::Recipe(name.into())
}
#[must_use]
pub fn output(item: impl Into<Name<'a>>) -> Self {
Self::Output(item.into())
}
#[must_use]
pub fn workshop(item: impl Into<Name<'a>>) -> Self {
Self::Workshop(item.into())
}
fn parts(
self,
) -> (
crate::abi::RecipeRuleKind,
&'static str,
std::borrow::Cow<'static, str>,
) {
use crate::abi::RecipeRuleKind;
match self {
Self::Recipe(name) => (RecipeRuleKind::RECIPE, "recipe", name.text()),
Self::Output(name) => (RecipeRuleKind::OUTPUT, "output", name.text()),
Self::Workshop(name) => (RecipeRuleKind::WORKSHOP, "workshop", name.text()),
Self::Hand => (RecipeRuleKind::WORKSHOP, "workshop", "hand".into()),
}
}
}
fn rule(rule: RecipeRule<'_>, disable: bool) -> Result<(), Off> {
let host = crate::host().ok_or_else(|| Off::new("recipe rules: no loader"))?;
let api = host.api();
let (kind, what, name) = rule.parts();
if name.trim().is_empty() {
return Err(Off::new(format!("recipe rule {what}: no name")));
}
let status = (api.recipe_rule)(
host.handle(),
kind,
crate::abi::Str::new(&name),
u32::from(disable),
);
crate::load::ok(status, (), || format!("recipe rule {what} {name:?}"))
}
pub fn disable(rule: RecipeRule<'_>) -> Result<(), Off> {
self::rule(rule, true)
}
pub fn enable(rule: RecipeRule<'_>) -> Result<(), Off> {
self::rule(rule, false)
}
#[must_use]
pub fn is_disabled(recipe: impl Into<Guid>) -> bool {
let Some(host) = crate::host() else {
return false;
};
let api = host.api();
let mut out = 0u32;
(api.recipe_disabled)(
host.handle(),
crate::RecipeId::new(recipe.into().fnv1a()),
&raw mut out,
)
.is_ok()
&& out != 0
}