use std::{borrow::Cow, fmt, marker::PhantomData};
use byteorder::{BigEndian, ReadBytesExt};
use serde::{de::Visitor, Deserialize, Serialize};
use serde_bytes::Bytes;
use crate::{BYTE_ARRAY_TOKEN, INT_ARRAY_TOKEN, LONG_ARRAY_TOKEN};
#[derive(Debug, Clone, Copy)]
pub struct ByteArray<'a> {
data: &'a [u8],
}
impl<'a> ByteArray<'a> {
pub fn iter(&self) -> ByteIter<'a> {
ByteIter(*self)
}
pub fn new(data: &'a [i8]) -> Self {
let (_, data, _) = unsafe { data.align_to::<u8>() };
Self { data }
}
pub(crate) fn from_bytes(data: &'a [u8]) -> Self {
Self { data }
}
}
impl<'a, 'de: 'a> Deserialize<'de> for ByteArray<'a> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct InnerVisitor<'a>(PhantomData<&'a ()>);
impl<'a, 'de: 'a> Visitor<'de> for InnerVisitor<'a> {
type Value = ByteArray<'a>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("byte array")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let token = map.next_key::<&str>()?.ok_or_else(|| {
serde::de::Error::custom("expected NBT byte array token, but got empty map")
})?;
let data = map.next_value::<&[u8]>()?;
if token == BYTE_ARRAY_TOKEN {
Ok(ByteArray::from_bytes(data))
} else {
Err(serde::de::Error::custom("expected NBT byte array token"))
}
}
}
deserializer.deserialize_map(InnerVisitor(PhantomData))
}
}
pub struct ByteIter<'a>(ByteArray<'a>);
impl<'a> Iterator for ByteIter<'a> {
type Item = i8;
fn next(&mut self) -> Option<Self::Item> {
self.0.data.read_i8().ok()
}
}
impl<'a> Serialize for ByteArray<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct Inner<'a> {
__fastnbt_byte_array: &'a Bytes,
}
Inner {
__fastnbt_byte_array: Bytes::new(self.data),
}
.serialize(serializer)
}
}
#[derive(Debug, Clone, Copy)]
pub struct IntArray<'a> {
data: ArrayRef<'a, i32>,
}
#[derive(Debug, Clone, Copy)]
enum ArrayRef<'a, T> {
NativeEndian(&'a [T]),
BigEndian(&'a [u8]),
}
impl<'a> IntArray<'a> {
pub fn iter(&self) -> IntIter<'a> {
IntIter(*self)
}
pub fn new(data: &'a [i32]) -> Self {
Self {
data: ArrayRef::NativeEndian(data),
}
}
pub(crate) fn from_bytes(data: &'a [u8]) -> Self {
Self {
data: ArrayRef::BigEndian(data),
}
}
}
impl<'a, 'de: 'a> Deserialize<'de> for IntArray<'a> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct InnerVisitor<'a>(PhantomData<&'a ()>);
impl<'a, 'de: 'a> Visitor<'de> for InnerVisitor<'a> {
type Value = IntArray<'a>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("int array")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let token = map.next_key::<&str>()?.ok_or_else(|| {
serde::de::Error::custom("expected NBT int array token, but got empty map")
})?;
let data = map.next_value::<&[u8]>()?;
if token == INT_ARRAY_TOKEN {
Ok(IntArray::from_bytes(data))
} else {
Err(serde::de::Error::custom("expected NBT int array token"))
}
}
}
deserializer.deserialize_map(InnerVisitor(PhantomData))
}
}
pub struct IntIter<'a>(IntArray<'a>);
impl<'a> Iterator for IntIter<'a> {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
match self.0.data {
ArrayRef::BigEndian(ref mut data) => data.read_i32::<BigEndian>().ok(),
ArrayRef::NativeEndian(ref mut data) => {
let ret = data.first()?;
*data = &data[1..];
Some(*ret)
}
}
}
}
impl<'a> Serialize for IntArray<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct Inner<'a> {
__fastnbt_int_array: &'a Bytes,
}
let mut tmp = vec![];
Inner {
__fastnbt_int_array: match self.data {
ArrayRef::BigEndian(data) => Bytes::new(data),
ArrayRef::NativeEndian(data) => {
tmp.extend(data.iter().flat_map(|i| i.to_be_bytes()));
Bytes::new(&tmp)
}
},
}
.serialize(serializer)
}
}
#[derive(Debug, Clone, Copy)]
pub struct LongArray<'a> {
data: ArrayRef<'a, i64>,
}
impl<'a> LongArray<'a> {
pub fn iter(&self) -> LongIter<'a> {
LongIter(*self)
}
pub fn new(data: &'a [i64]) -> Self {
Self {
data: ArrayRef::NativeEndian(data),
}
}
pub(crate) fn from_bytes(data: &'a [u8]) -> Self {
Self {
data: ArrayRef::BigEndian(data),
}
}
}
impl<'a, 'de: 'a> Deserialize<'de> for LongArray<'a> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct InnerVisitor<'a>(PhantomData<&'a ()>);
impl<'a, 'de: 'a> Visitor<'de> for InnerVisitor<'a> {
type Value = LongArray<'a>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("long array")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let token = map.next_key::<&str>()?.ok_or_else(|| {
serde::de::Error::custom("expected NBT long array token, but got empty map")
})?;
let data = map.next_value::<&[u8]>()?;
if token == LONG_ARRAY_TOKEN {
Ok(LongArray::from_bytes(data))
} else {
Err(serde::de::Error::custom("expected NBT long array token"))
}
}
}
deserializer.deserialize_map(InnerVisitor(PhantomData))
}
}
pub struct LongIter<'a>(LongArray<'a>);
impl<'a> Iterator for LongIter<'a> {
type Item = i64;
fn next(&mut self) -> Option<Self::Item> {
match self.0.data {
ArrayRef::BigEndian(ref mut data) => data.read_i64::<BigEndian>().ok(),
ArrayRef::NativeEndian(ref mut data) => {
let ret = data.first()?;
*data = &data[1..];
Some(*ret)
}
}
}
}
impl<'a> Serialize for LongArray<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct Inner<'a> {
__fastnbt_long_array: &'a Bytes,
}
let mut tmp = vec![];
Inner {
__fastnbt_long_array: match self.data {
ArrayRef::BigEndian(data) => Bytes::new(data),
ArrayRef::NativeEndian(data) => {
tmp.extend(data.iter().flat_map(|i| i.to_be_bytes()));
Bytes::new(&tmp)
}
},
}
.serialize(serializer)
}
}
struct CowStr<'a>(Cow<'a, str>);
impl<'de> serde::Deserialize<'de> for CowStr<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(CowStrVisitor)
}
}
struct CowStrVisitor;
impl<'de> serde::de::Visitor<'de> for CowStrVisitor {
type Value = CowStr<'de>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(CowStr(Cow::Borrowed(value)))
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(CowStr(Cow::Owned(value.to_owned())))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(CowStr(Cow::Owned(value)))
}
}
pub fn deserialize_cow_str<'de, D>(deserializer: D) -> Result<Cow<'de, str>, D::Error>
where
D: serde::Deserializer<'de>,
{
let wrapper = CowStr::deserialize(deserializer)?;
Ok(wrapper.0)
}