diff --git a/src/ser.rs b/src/ser.rs index 9a4d514..07e5b52 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -715,10 +715,10 @@ impl ser::SerializeMap for NoOp { /// /// print!("Serialized: {:?}", serialized); /// ``` -pub fn i8_array<'a, T, S>(array: &'a T, serializer: S) -> std::result::Result +pub fn i8_array(array: T, serializer: S) -> std::result::Result where - &'a T: IntoIterator, - <&'a T as IntoIterator>::Item: std::borrow::Borrow, + T: IntoIterator, + ::Item: std::borrow::Borrow, S: serde::ser::Serializer, { array_serializer!("i8_array", array, serializer) @@ -755,10 +755,10 @@ where /// /// print!("Serialized: {:?}", serialized); /// ``` -pub fn i32_array<'a, T, S>(array: &'a T, serializer: S) -> std::result::Result +pub fn i32_array(array: T, serializer: S) -> std::result::Result where - &'a T: IntoIterator, - <&'a T as IntoIterator>::Item: std::borrow::Borrow, + T: IntoIterator, + ::Item: std::borrow::Borrow, S: serde::ser::Serializer, { array_serializer!("i32_array", array, serializer) @@ -795,10 +795,10 @@ where /// /// print!("Serialized: {:?}", serialized); /// ``` -pub fn i64_array<'a, T, S>(array: &'a T, serializer: S) -> std::result::Result +pub fn i64_array(array: T, serializer: S) -> std::result::Result where - &'a T: IntoIterator, - <&'a T as IntoIterator>::Item: std::borrow::Borrow, + T: IntoIterator, + ::Item: std::borrow::Borrow, S: serde::ser::Serializer, { array_serializer!("i64_array", array, serializer) diff --git a/tests/serde_basics.rs b/tests/serde_basics.rs index 7f02f5b..8f1f163 100644 --- a/tests/serde_basics.rs +++ b/tests/serde_basics.rs @@ -6,7 +6,7 @@ extern crate nbt; use std::collections::HashMap; -use serde::Serializer; +use serde::{Serialize, Serializer}; /// Helper function that asserts data of type T can be serialized into and /// deserialized from `bytes`. `name` is an optional header for the top-level @@ -182,11 +182,16 @@ fn nested_i32_array(outer_arr: &Vec>, serializer: S) -> Result); + #[derive(Debug)] + struct Wrapper<'a>(&'a Vec); - // clone should be optimized to a no-op - serializer.collect_seq(outer_arr.iter().map(|vec| Wrapper(vec.clone()))) + impl<'a> Serialize for Wrapper<'a> { + fn serialize(&self, serializer: S) -> Result { + nbt::i32_array(self.0, serializer) + } + } + + serializer.collect_seq(outer_arr.iter().map(|vec| Wrapper(vec))) } #[test] @@ -323,6 +328,44 @@ fn roundtrip_long_array() { assert_roundtrip_eq(nbt, &bytes, None); } +#[derive(Debug, PartialEq, Serialize)] +struct CustomSerializerArrayNbt { + #[serde(serialize_with = "shift_right_serializer")] + data: Vec, +} + +// We want to serialize an i16 vector as a ByteArray by shifting every element right by 8 bits +fn shift_right_serializer(original_array: &Vec, serializer: S) -> Result +where + S: Serializer, +{ + nbt::i8_array(original_array.iter().map(|&i| (i >> 8) as i8), serializer) +} + +#[test] +fn serialize_custom_serializer_array() { + let nbt = CustomSerializerArrayNbt { + data: vec![0xAABBu16 as i16, 0x3400, 0x1234, 0x0012], + }; + + #[rustfmt::skip] + let bytes = vec![ + 0x0a, + 0x00, 0x00, + 0x07, + 0x00, 0x04, + 0x64, 0x61, 0x74, 0x61, + 0x00, 0x00, 0x00, 0x04, // Length. + 0xAA, 0x34, 0x12, 0x00, // Content. + 0x00 + ]; + + let mut dst = Vec::with_capacity(bytes.len()); + + nbt::ser::to_writer(&mut dst, &nbt, None).expect("NBT serialization."); + assert_eq!(bytes, &dst[..]); +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] struct BoolNbt { data: bool,