mirror of
https://mzte.de/git/LordMZTE/sercon.git
synced 2024-05-19 07:23:54 +02:00
67 lines
1.9 KiB
Rust
67 lines
1.9 KiB
Rust
use std::io::{Read, Write};
|
|
|
|
use flate2::{
|
|
bufread::{GzDecoder, ZlibDecoder},
|
|
write::GzEncoder,
|
|
Compression,
|
|
};
|
|
use miette::{Context, IntoDiagnostic};
|
|
use sercon_base::Backend;
|
|
use serde_value::Value;
|
|
|
|
#[derive(Default)]
|
|
pub struct NbtBackend;
|
|
|
|
impl Backend for NbtBackend {
|
|
fn serialize(&self, out: &mut dyn Write, data: Value) -> miette::Result<()> {
|
|
let gz = GzEncoder::new(out, Compression::new(5));
|
|
fastnbt::to_writer(gz, &data)
|
|
.into_diagnostic()
|
|
.wrap_err("failed to serialize NBT data")?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn deserialize(&self, data: &mut dyn Read) -> miette::Result<Value> {
|
|
let mut vec = vec![];
|
|
data.read_to_end(&mut vec).into_diagnostic()?;
|
|
|
|
let compression = vec
|
|
.get(0..2)
|
|
.map(|m| match m {
|
|
[0x1f, 0x8b] => CompressionType::Gzip,
|
|
[0x78, 0x01] | [0x78, 0x9C] | [0x78, 0xDA] => CompressionType::Zlib,
|
|
_ => CompressionType::None,
|
|
})
|
|
.unwrap_or(CompressionType::None);
|
|
let mut decomp = vec![];
|
|
match compression {
|
|
CompressionType::Gzip => {
|
|
GzDecoder::new(&vec[..])
|
|
.read_to_end(&mut decomp)
|
|
.into_diagnostic()
|
|
.wrap_err("data gz decompression failed")?;
|
|
},
|
|
CompressionType::Zlib => {
|
|
ZlibDecoder::new(&vec[..])
|
|
.read_to_end(&mut decomp)
|
|
.into_diagnostic()
|
|
.wrap_err("data zlib decompression failed")?;
|
|
},
|
|
CompressionType::None => decomp.copy_from_slice(&vec),
|
|
}
|
|
|
|
fastnbt::from_bytes(&decomp)
|
|
.into_diagnostic()
|
|
.wrap_err("NBT deserialization failed")
|
|
}
|
|
}
|
|
|
|
impl_filetype_backend!(NbtBackend, ["nbt"]);
|
|
|
|
enum CompressionType {
|
|
Gzip,
|
|
Zlib,
|
|
None,
|
|
}
|