From b815a9b06b036db7c982c33825ed11c10d2c09a3 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 18 Apr 2021 15:27:22 +0200 Subject: [PATCH] Add blocks api Signed-off-by: trivernis --- src/api/blocks.rs | 41 +++++++++++++++++++++++++++++ src/api/mod.rs | 8 ++++-- src/api/tests/blocks.rs | 36 +++++++++++++++++++++++++ src/api/tests/mod.rs | 1 + src/models/block.rs | 58 +++++++++++++++++++++++++++++++++++++++++ src/models/mod.rs | 1 + 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/api/blocks.rs create mode 100644 src/api/tests/blocks.rs create mode 100644 src/models/block.rs diff --git a/src/api/blocks.rs b/src/api/blocks.rs new file mode 100644 index 0000000..21252cd --- /dev/null +++ b/src/api/blocks.rs @@ -0,0 +1,41 @@ +use crate::data::{get_version_specific_file, BLOCKS_FILE}; +use crate::models::block::Block; +use crate::models::version::Version; +use crate::DataResult; +use std::collections::HashMap; +use std::iter::FromIterator; +use std::sync::Arc; + +pub struct Blocks { + version: Arc, +} + +impl Blocks { + pub fn new(version: Arc) -> Self { + Self { version } + } + + /// Returns the list of blocks + pub fn blocks_array(&self) -> DataResult> { + let content = get_version_specific_file(&self.version, BLOCKS_FILE)?; + let blocks = serde_json::from_str::>(&content)?; + + Ok(blocks) + } + + /// Returns the blocks indexed by ID + pub fn blocks(&self) -> DataResult> { + let blocks = self.blocks_array()?; + let blocks_map = HashMap::from_iter(blocks.into_iter().map(|b| (b.id, b))); + + Ok(blocks_map) + } + + /// Returns the blocks indexed by name + pub fn blocks_by_name(&self) -> DataResult> { + let blocks = self.blocks_array()?; + let blocks_map = HashMap::from_iter(blocks.into_iter().map(|b| (b.name.clone(), b))); + + Ok(blocks_map) + } +} diff --git a/src/api/mod.rs b/src/api/mod.rs index c8c022b..6e9e594 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -4,14 +4,16 @@ use crate::api::loot::Loot; use crate::api::recipes::Recipes; use crate::models::version::Version; use std::sync::Arc; +use crate::api::blocks::Blocks; #[cfg(test)] mod tests; +pub mod blocks; pub mod enchantments; pub mod items; -mod loot; -mod recipes; +pub mod loot; +pub mod recipes; pub mod versions; pub struct Api { @@ -20,6 +22,7 @@ pub struct Api { pub recipes: Recipes, pub enchantments: Enchantments, pub loot: Loot, + pub blocks: Blocks, } impl Api { @@ -31,6 +34,7 @@ impl Api { recipes: Recipes::new(Arc::clone(&version)), enchantments: Enchantments::new(Arc::clone(&version)), loot: Loot::new(Arc::clone(&version)), + blocks: Blocks::new(Arc::clone(&version)) } } } diff --git a/src/api/tests/blocks.rs b/src/api/tests/blocks.rs new file mode 100644 index 0000000..edbc58d --- /dev/null +++ b/src/api/tests/blocks.rs @@ -0,0 +1,36 @@ +use crate::api::tests::{get_api, get_test_versions}; + +#[test] +pub fn test_blocks_array() { + let versions = get_test_versions(); + + for version in versions { + let api = get_api(version); + assert_ne!(api.blocks.blocks_array().unwrap().len(), 0) + } +} + +#[test] +pub fn test_blocks_by_name() { + let versions = get_test_versions(); + + for version in versions { + let api = get_api(version); + let by_name = api.blocks.blocks_by_name().unwrap(); + assert!(by_name.get("dirt").is_some()); + assert!(by_name.get("stone").is_some()); + assert_eq!(by_name.get("grass").unwrap().stack_size, 64) + } +} + +#[test] +pub fn test_blocks_by_id() { + let versions = get_test_versions(); + + for version in versions { + let api = get_api(version); + let by_name = api.blocks.blocks().unwrap(); + assert!(by_name.get(&1).is_some()); + assert!(by_name.get(&5).is_some()); + } +} diff --git a/src/api/tests/mod.rs b/src/api/tests/mod.rs index 964cd17..bdc8339 100644 --- a/src/api/tests/mod.rs +++ b/src/api/tests/mod.rs @@ -7,6 +7,7 @@ mod items; mod loot; mod recipes; mod versions; +mod blocks; fn get_api(version: Version) -> Api { Api::new(version) diff --git a/src/models/block.rs b/src/models/block.rs new file mode 100644 index 0000000..2105edd --- /dev/null +++ b/src/models/block.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct Block { + pub id: u32, + pub display_name: String, + pub name: String, + pub hardness: Option, + pub stack_size: u8, + pub diggable: bool, + pub bounding_box: BoundingBox, + pub material: Option, + pub harvest_tool: Option>, + pub variations: Option>, + pub drops: Vec, + pub transparent: bool, + pub emit_light: u8, + pub filter_light: u8, + pub min_state_id: Option, + pub max_state_id: Option, + pub default_state: Option, + #[serde(alias = "resistance")] + pub blast_resistance: Option, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub enum BoundingBox { + Block, + Empty, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct Variation { + metadata: u32, + display_name: String, + description: Option, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct State { + pub name: String, + #[serde(alias = "type")] + pub state_type: StateType, + pub values: Option>, + pub num_values: u32, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub enum StateType { + Enum, + Bool, + Int, +} diff --git a/src/models/mod.rs b/src/models/mod.rs index 71f19a3..3997629 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,3 +1,4 @@ +pub mod block; pub mod block_loot; pub mod enchantment; pub mod entity_loot;