diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..3b458be 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/src/api/mod.rs b/src/api/mod.rs index a6a670a..c771c2b 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,4 +1,5 @@ use crate::api::items::Items; +use crate::api::recipes::Recipes; use crate::models::version::Version; use std::sync::Arc; @@ -6,11 +7,13 @@ use std::sync::Arc; mod tests; pub mod items; +mod recipes; pub mod versions; pub struct Api { - version: Arc, - items: Items, + pub version: Arc, + pub items: Items, + pub recipes: Recipes, } impl Api { @@ -19,6 +22,7 @@ impl Api { Self { version: Arc::clone(&version), items: Items::new(Arc::clone(&version)), + recipes: Recipes::new(Arc::clone(&version)), } } } diff --git a/src/api/recipes.rs b/src/api/recipes.rs new file mode 100644 index 0000000..2c802af --- /dev/null +++ b/src/api/recipes.rs @@ -0,0 +1,23 @@ +use crate::data::{get_version_specific_file, RECIPES_FILE}; +use crate::models::recipe::Recipe; +use crate::models::version::Version; +use crate::{DataError, DataResult}; +use std::collections::HashMap; +use std::sync::Arc; + +#[derive(Clone, Debug)] +pub struct Recipes { + version: Arc, +} + +impl Recipes { + pub fn new(version: Arc) -> Self { + Self { version } + } + + /// Returns a list of recipes indexed by item ID + pub fn recipes(&self) -> DataResult>> { + let content = get_version_specific_file(&self.version, RECIPES_FILE)?; + serde_json::from_str::>>(&*content).map_err(DataError::from) + } +} diff --git a/src/api/tests/items.rs b/src/api/tests/items.rs index a07c978..5d915b4 100644 --- a/src/api/tests/items.rs +++ b/src/api/tests/items.rs @@ -9,3 +9,16 @@ pub fn test_items_array() { assert_ne!(api.items.items_array().unwrap().len(), 0) } } + +#[test] +pub fn test_items_by_name() { + let versions = get_test_versions(); + + for version in versions { + let api = get_api(version); + let by_name = api.items.items_by_name().unwrap(); + assert!(by_name.get("bread").is_some()); + assert!(by_name.get("stone").is_some()); + assert_eq!(by_name.get("ender_pearl").unwrap().stack_size, 16) + } +} diff --git a/src/api/tests/mod.rs b/src/api/tests/mod.rs index c1c0aa2..ec3f0c7 100644 --- a/src/api/tests/mod.rs +++ b/src/api/tests/mod.rs @@ -3,6 +3,7 @@ use crate::api::Api; use crate::models::version::Version; mod items; +mod recipes; mod versions; fn get_api(version: Version) -> Api { diff --git a/src/api/tests/recipes.rs b/src/api/tests/recipes.rs new file mode 100644 index 0000000..087e012 --- /dev/null +++ b/src/api/tests/recipes.rs @@ -0,0 +1,14 @@ +use crate::api::tests::{get_api, get_test_versions}; + +#[test] +pub fn test_recipes() { + let versions = get_test_versions(); + + for version in versions { + let api = get_api(version); + let recipes = api.recipes.recipes().unwrap(); + let bread_id = api.items.items_by_name().unwrap().get("bread").unwrap().id; + assert_ne!(recipes.len(), 0); + assert!(recipes.get(&bread_id).is_some()); + } +} diff --git a/src/api/versions.rs b/src/api/versions.rs index 76b483a..eb2b0cf 100644 --- a/src/api/versions.rs +++ b/src/api/versions.rs @@ -33,8 +33,6 @@ pub fn latest_stable() -> DataResult { /// Returns a list of available version information pub(crate) fn available_versions() -> DataResult> { - Ok(get_common_file(VERSIONS_FILE)? - .split_whitespace() - .map(|s| s.to_string()) - .collect()) + let content = get_common_file(VERSIONS_FILE)?; + serde_json::from_str::>(&*content).map_err(DataError::from) } diff --git a/src/data/mod.rs b/src/data/mod.rs index ad5e603..ecddd53 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -41,7 +41,6 @@ pub fn get_version_specific_file(version: &Version, filename: &str) -> DataResul version.previous_major(), version.previous_major_first(), ]; - println!("{:?}", search_folders); let mut data = None; for folder in search_folders { diff --git a/src/models/mod.rs b/src/models/mod.rs index afbce8b..1a667d7 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,2 +1,3 @@ pub mod item; +pub mod recipe; pub mod version; diff --git a/src/models/recipe.rs b/src/models/recipe.rs new file mode 100644 index 0000000..12d5047 --- /dev/null +++ b/src/models/recipe.rs @@ -0,0 +1,46 @@ +#[derive(Deserialize, Debug, Clone)] +#[serde( + rename_all(deserialize = "camelCase", serialize = "snake_case"), + untagged +)] +pub enum Recipe { + Shaped(ShapedRecipe), + Shapeless(ShapelessRecipe), +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct ShapedRecipe { + result: RecipeItem, + in_shape: Shape, + out_shape: Option, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct ShapelessRecipe { + result: RecipeItem, + ingredients: Vec, +} + +pub type Shape = Vec>; + +#[derive(Deserialize, Debug, Clone)] +#[serde( + rename_all(deserialize = "camelCase", serialize = "snake_case"), + untagged +)] +pub enum RecipeItem { + ID(u32), + IDMetadataArray([u32; 2]), + IDMetadataCountObject(IDMetadataCountObject), + Null(Option<()>), +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all(deserialize = "camelCase", serialize = "snake_case"))] +pub struct IDMetadataCountObject { + id: i32, + metadata: Option, + count: Option, +}