Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ItemStack refactor #12

Merged
merged 14 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
mod biome;
pub mod block;
mod consts;
mod enchantment;
mod entity;
mod gamemode;
mod gamerules;
Expand All @@ -13,7 +12,6 @@ mod positions;

pub use biome::Biome;
pub use consts::*;
pub use enchantment::{Enchantment, EnchantmentKind};
pub use entity::EntityKind;
pub use gamemode::Gamemode;
pub use gamerules::GameRules;
Expand Down
16 changes: 11 additions & 5 deletions crates/generators/python/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from re import split
from pathlib import Path

from typing import List

LIBCRAFT_ROOT = Path(__file__).parents[3]
PRISMARINEJS_BASE_PATH = Path(__file__).parents[1] / "minecraft-data" / "data" / "pc"
Expand Down Expand Up @@ -141,16 +142,21 @@ def generate_enum_property(
return result


def generate_enum(name: str, variants: list[str]) -> str:
"""Generates an enum definition with the provided variants."""
def generate_enum(name: str, variants: List[str], derives: List[str] = [], prelude: str = "") -> str:
"""Generates an enum definition with the provided variants and extra derives."""
body = ','.join(variants) + ','

return f"""
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
extra_derives = "" if len(derives) == 0 else ',' + ','.join(derives)
output = f"""
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord{extra_derives})]"""
if len(prelude) != 0:
output += f"""
{prelude}"""
output += f"""
pub enum {name} {{
{body}
}}
"""
return output


def camel_case(string: str) -> str:
Expand Down
47 changes: 46 additions & 1 deletion crates/generators/python/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,56 @@
else:
durabilities[variant] = f"Some({durability})"

output_data = "#[derive(serde::Serialize, serde::Deserialize)]" + generate_enum("Item", items)
output_data = "use serde::{Serialize, Deserialize};"

output_data += generate_enum("Item", items, derives=["Serialize", "Deserialize"],
prelude="#[serde(try_from = \"String\", into = \"&'static str\")]")
output_data += generate_enum_property("Item", "id", "u32", ids, True)
output_data += generate_enum_property("Item", "name", "&str", names, True, "&'static str")
output_data += generate_enum_property("Item", "display_name", "&str", display_names, False, "&'static str")
output_data += generate_enum_property("Item", "stack_size", "u32", stack_sizes)
output_data += generate_enum_property("Item", "durability", "Option<u32>", durabilities)

output_data += f"""
use std::convert::TryFrom;

impl TryFrom<String> for Item {{
PauMAVA marked this conversation as resolved.
Show resolved Hide resolved
type Error = &'static str;

fn try_from(value: String) -> Result<Self, Self::Error> {{
if let Some(item) = Item::from_name(value.as_str()) {{
Ok(item)
}} else {{
Err("Unknown item name.")
}}
}}
}}
"""

output_data += f"""
use std::convert::Into;

impl Into<&'static str> for Item {{
fn into(self) -> &'static str {{
self.name()
}}
}}
"""

output_data += f"""
use std::str::FromStr;

impl FromStr for Item {{
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {{
if let Some(item) = Item::from_name(s) {{
Ok(item)
}} else {{
Err("Unknown item name.")
}}
}}
}}
"""

output("crates/items/src/item.rs", output_data)
4 changes: 2 additions & 2 deletions crates/items/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "libcraft-items"
version = "0.1.0"
authors = ["Kalle Kankaanpää"]
authors = ["Kalle Kankaanpää", "Pau Machetti <paumachetti@gmail.com>"]
edition = "2018"

[dependencies]
serde = { version = "1", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use serde::{Deserialize, Serialize};

/// An enchantment attached to an item.
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Enchantment {
#[serde(rename = "id")]
kind: EnchantmentKind,
Expand Down Expand Up @@ -54,7 +54,7 @@ impl Enchantment {
}

/// Kind of an enchantment.
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EnchantmentKind {
AquaAffinity,
Expand Down
50 changes: 50 additions & 0 deletions crates/items/src/inventory_slot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use crate::item_stack::ItemStackError;
use crate::ItemStack;
use core::mem;

/// Represents an Inventory slot. May be empty
/// or filled (contains an `ItemStack`).
pub enum InventorySlot {
Filled(ItemStack),
Empty,
}

impl Default for InventorySlot {
fn default() -> Self {
InventorySlot::Empty
}
}

impl InventorySlot {
/// Tries to take all items from the `InventorySlot`.
/// If the `InventorySlot` is filled returns the `ItemStack`.
/// If the `InventorySlot` is empty returns `None`.
pub fn take_all(&mut self) -> Option<ItemStack> {
match mem::take(self) {
Self::Filled(stack) => Some(stack),
Self::Empty => None,
}
}

/// Tries to take (split) the specified amount from the associated
/// `ItemStack` to this `InventorySlot`. If this `InventorySlot` is
/// empty, the specified amount is zero, or the resulting stack is
/// empty will return the `ItemStackError::EmptyStack` error. If the
/// amount to take is bigger than the current amount it will return
/// the `ItemStackError::NotEnoughAmount` error. On success returns
/// the taken part of the `ItemStack` as a new one.
pub fn take(&mut self, amount: u32) -> Result<ItemStack, ItemStackError> {
let split = match mem::take(self) {
Self::Empty => return Err(ItemStackError::EmptyStack),
Self::Filled(mut stack) => stack.split(amount),
};
let (stack, res) = match split {
Ok((original, new)) => (original, Ok(new)),
Err((original, error)) => (Some(original), Err(error)),
};
if let Some(stack) = stack {
*self = Self::Filled(stack)
}
res
}
}
41 changes: 38 additions & 3 deletions crates/items/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file is @generated. Please do not edit.
#[derive(
serde::Serialize, serde::Deserialize, Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord,
)]
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(try_from = "String", into = "&'static str")]
pub enum Item {
Air,
Stone,
Expand Down Expand Up @@ -7872,3 +7872,38 @@ impl Item {
}
}
}
use std::convert::TryFrom;

impl TryFrom<String> for Item {
type Error = &'static str;

fn try_from(value: String) -> Result<Self, Self::Error> {
if let Some(item) = Item::from_name(value.as_str()) {
Ok(item)
} else {
Err("Unknown item name.")
}
}
}

use std::convert::Into;

impl Into<&'static str> for Item {
fn into(self) -> &'static str {
self.name()
}
}

use std::str::FromStr;

impl FromStr for Item {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(item) = Item::from_name(s) {
Ok(item)
} else {
Err("Unknown item name.")
}
}
}
Loading