steel_registry/recipe/
ingredient.rs1use steel_utils::Identifier;
4
5use crate::{REGISTRY, TaggedRegistryExt, item_stack::ItemStack, items::ItemRef};
6
7#[derive(Debug, Clone)]
10pub enum Ingredient {
11 Empty,
13 Item(ItemRef),
15 Tag(Identifier),
17 Choice(&'static [ItemRef]),
19}
20
21impl Ingredient {
22 #[must_use]
24 pub fn test(&self, stack: &ItemStack) -> bool {
25 match self {
26 Self::Empty => stack.is_empty(),
27 Self::Item(item) => !stack.is_empty() && *item == stack.item,
28 Self::Tag(tag) => {
29 if stack.is_empty() {
30 return false;
31 }
32 REGISTRY.items.is_in_tag(stack.item, tag)
33 }
34 Self::Choice(items) => {
35 if stack.is_empty() {
36 return false;
37 }
38 items.contains(&stack.item)
39 }
40 }
41 }
42
43 #[must_use]
45 pub const fn is_empty(&self) -> bool {
46 matches!(self, Self::Empty)
47 }
48
49 #[must_use]
51 pub fn get_items(&self) -> Vec<ItemRef> {
52 match self {
53 Self::Empty => Vec::new(),
54 Self::Item(item) => vec![*item],
55 Self::Tag(tag) => REGISTRY.items.get_tag(tag).unwrap_or_default(),
56 Self::Choice(items) => items.to_vec(),
57 }
58 }
59
60 #[must_use]
62 pub fn eq_ingredient(&self, other: &Self) -> bool {
63 match (self, other) {
64 (Self::Empty, Self::Empty) => true,
65 (Self::Item(a), Self::Item(b)) => a == b,
66 (Self::Tag(a), Self::Tag(b)) => a == b,
67 (Self::Choice(a), Self::Choice(b)) => {
68 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x == y)
69 }
70 _ => false,
71 }
72 }
73}