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 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
56 .items
57 .get_tag(tag)
58 .map(|items| items.to_vec())
59 .unwrap_or_default(),
60 Self::Choice(items) => items.to_vec(),
61 }
62 }
63
64 #[must_use]
66 pub fn eq_ingredient(&self, other: &Self) -> bool {
67 match (self, other) {
68 (Self::Empty, Self::Empty) => true,
69 (Self::Item(a), Self::Item(b)) => a == b,
70 (Self::Tag(a), Self::Tag(b)) => a == b,
71 (Self::Choice(a), Self::Choice(b)) => {
72 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x == y)
73 }
74 _ => false,
75 }
76 }
77}