use std::io::Read;
use base64::Engine;
use flate2::read::GzDecoder;
use serde_json::Value;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NbtError {
#[error("invalid base64: {0}")]
Base64(#[from] base64::DecodeError),
#[error("gzip decompression failed: {0}")]
Gzip(#[source] std::io::Error),
#[error("invalid NBT: {0}")]
Nbt(#[from] fastnbt::error::Error),
#[error("no NBT data field present")]
MissingData,
}
pub fn decode_nbt(encoded: &str) -> Result<fastnbt::Value, NbtError> {
let compressed = base64::engine::general_purpose::STANDARD.decode(encoded.trim())?;
let mut decoder = GzDecoder::new(&compressed[..]);
let mut bytes = Vec::new();
decoder.read_to_end(&mut bytes).map_err(NbtError::Gzip)?;
Ok(fastnbt::from_bytes(&bytes)?)
}
pub fn decode_inventory(section: &Value) -> Result<fastnbt::Value, NbtError> {
let encoded = match section {
Value::String(s) => s.as_str(),
Value::Object(map) => map
.get("data")
.and_then(Value::as_str)
.ok_or(NbtError::MissingData)?,
_ => return Err(NbtError::MissingData),
};
decode_nbt(encoded)
}