use std::{collections::HashMap, hint::black_box, io::Cursor}; use simdnbt::borrow::BaseNbt; #[derive(Clone, PartialEq, Debug)] pub struct Item { pub id: i16, pub damage: i16, pub count: i8, pub head_texture_id: Option, pub skyblock_id: Option, pub reforge: Option, pub display: ItemDisplay, pub enchantments: HashMap, pub timestamp: Option, } #[derive(Clone, PartialEq, Debug)] pub struct ItemDisplay { pub name: String, pub lore: Vec, pub has_glint: bool, pub color: Option, } fn items_from_nbt(nbt: BaseNbt) -> Option>> { let mut items = Vec::new(); for item_nbt in nbt .list("i") .and_then(|list| list.compounds()) .unwrap_or_default() { // check if "id" is present, if not, skip if !item_nbt.contains("id") { // this just means the item isn't present items.push(None); continue; } let item_tag = item_nbt.compound("tag")?; let item_extra_attributes = item_tag.compound("ExtraAttributes"); let item_display = item_tag.compound("display"); items.push(Some(Item { id: item_nbt.short("id")?, damage: item_nbt.short("Damage")?, count: item_nbt.byte("Count")?, head_texture_id: item_tag .compound("SkullOwner") .and_then(|skull_owner| skull_owner.compound("Properties")) .and_then(|properties| properties.list("textures")) .and_then(|textures| textures.compounds()) .and_then(|textures| textures.first()) .and_then(|texture| texture.string("Value")) // the real program does some base64+json decoding here but that's unnecessary for the benchmark .map(|value| value.to_string()), skyblock_id: item_extra_attributes .and_then(|e| e.string("id")) .map(|id| id.to_string()), reforge: item_extra_attributes .and_then(|e| e.string("modifier")) .map(|id| id.to_string()), display: ItemDisplay { name: item_display .and_then(|d| d.string("Name")) .map(|n| n.to_string()) .unwrap_or_default(), lore: item_display .and_then(|d| d.list("Lore")) .and_then(|l| l.strings()) .map(|l| l.iter().map(|s| s.to_string()).collect()) .unwrap_or_default(), color: item_display.and_then(|d| d.int("color")), has_glint: item_extra_attributes .map(|e| e.contains("ench")) .unwrap_or_default(), }, enchantments: item_extra_attributes .and_then(|e| e.compound("enchantments")) .map(|e| { e.iter() .map(|(k, v)| (k.to_string(), v.int().unwrap_or_default())) .collect() }) .unwrap_or_default(), timestamp: item_extra_attributes .and_then(|e| e.string("timestamp")) .map(|t| t.to_string()), })); } Some(items) } fn main() { let input = black_box(include_bytes!("../tests/hypixel.nbt")); for _ in 0..1 { let nbt = simdnbt::borrow::read(&mut Cursor::new(input)); let nbt = black_box(nbt.unwrap().unwrap()); black_box(items_from_nbt(nbt)); } }