pub use blob::Blob;
pub use generic::{TdfGeneric, TdfGenericInner, TdfGenericValue};
pub use group::GroupSlice;
pub use map::TdfMap;
pub use object_id::ObjectId;
pub use object_type::ObjectType;
pub use tagged_union::TaggedUnion;
pub use var_int_list::VarIntList;
use crate::{error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer};
pub fn serialize_vec<V>(value: &V) -> Vec<u8>
where
V: TdfSerialize,
{
let mut output = Vec::new();
value.serialize(&mut output);
output
}
#[cfg(feature = "bytes")]
pub mod bytes {
use bytes::Bytes;
use crate::{serialize_vec, TdfSerialize};
#[inline]
pub fn serialize_bytes<V>(value: &V) -> Bytes
where
V: TdfSerialize,
{
Bytes::from(serialize_vec(value))
}
}
pub trait TdfDeserialize<'de>: Sized {
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self>;
}
pub trait TdfDeserializeOwned: Sized {
fn deserialize_owned(r: &mut TdfDeserializer<'_>) -> DecodeResult<Self>;
}
impl<T> TdfDeserialize<'_> for T
where
T: TdfDeserializeOwned,
{
#[inline]
fn deserialize(r: &mut TdfDeserializer<'_>) -> DecodeResult<Self> {
Self::deserialize_owned(r)
}
}
pub trait TdfSerialize: Sized {
fn serialize<S: TdfSerializer>(&self, w: &mut S);
}
pub trait TdfSerializeOwned: Sized {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S);
}
pub trait TdfTyped {
const TYPE: TdfType;
}
pub mod var_int {
use super::{TdfDeserializeOwned, TdfSerializeOwned, TdfTyped};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
TdfSerialize,
};
pub fn skip_var_int(r: &mut TdfDeserializer) -> DecodeResult<()> {
let mut byte = r.read_byte()?;
while byte >= 0x80 {
byte = r.read_byte()?;
}
Ok(())
}
macro_rules! impl_serialize_int {
($value:ident, $w:ident) => {{
if $value < 0x40 {
$w.write_byte($value as u8);
return;
}
$w.write_byte((($value & 0x3f) | 0x80) as u8);
let mut value = $value >> 6;
while value >= 0x80 {
$w.write_byte(((value & 0x7f) | 0x80) as u8);
value >>= 7;
}
$w.write_byte(value as u8)
}};
}
macro_rules! impl_deserialize_int {
($ty:ty, $r:ident) => {{
let mut byte: u8 = $r.read_byte()?;
let mut result: $ty = (byte & 0x3F) as $ty;
let mut shift = 6;
while byte >= 0x80 {
byte = $r.read_byte()?;
result |= ((byte & 0x7f) as $ty).wrapping_shl(shift);
shift += 7;
}
Ok(result)
}};
}
impl TdfDeserializeOwned for bool {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = u8::deserialize_owned(r)?;
Ok(value == 1)
}
}
impl TdfSerializeOwned for bool {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
w.write_byte(self as u8)
}
}
impl TdfSerialize for bool {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for bool {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for u8 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
impl_deserialize_int!(u8, r)
}
}
impl TdfSerializeOwned for u8 {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
impl_serialize_int!(self, w)
}
}
impl TdfSerialize for u8 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for u8 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for i8 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = u8::deserialize_owned(r)?;
Ok(value as i8)
}
}
impl TdfSerializeOwned for i8 {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
(self as u8).serialize_owned(w)
}
}
impl TdfSerialize for i8 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for i8 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for u16 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
impl_deserialize_int!(u16, r)
}
}
impl TdfSerializeOwned for u16 {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
impl_serialize_int!(self, w)
}
}
impl TdfSerialize for u16 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for u16 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for i16 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = u16::deserialize_owned(r)?;
Ok(value as i16)
}
}
impl TdfSerializeOwned for i16 {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
(self as u16).serialize_owned(w);
}
}
impl TdfSerialize for i16 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for i16 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for u32 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
impl_deserialize_int!(u32, r)
}
}
impl TdfSerializeOwned for u32 {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
impl_serialize_int!(self, w)
}
}
impl TdfSerialize for u32 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for u32 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for i32 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = u32::deserialize_owned(r)?;
Ok(value as i32)
}
}
impl TdfSerializeOwned for i32 {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
(self as u32).serialize_owned(w);
}
}
impl TdfSerialize for i32 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for i32 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for u64 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
impl_deserialize_int!(u64, r)
}
}
impl TdfSerializeOwned for u64 {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
impl_serialize_int!(self, w);
}
}
impl TdfSerialize for u64 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for u64 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for i64 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = u64::deserialize_owned(r)?;
Ok(value as i64)
}
}
impl TdfSerializeOwned for i64 {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
(self as u64).serialize_owned(w);
}
}
impl TdfSerialize for i64 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for i64 {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for usize {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
impl_deserialize_int!(usize, r)
}
}
impl TdfSerializeOwned for usize {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
impl_serialize_int!(self, w);
}
}
impl TdfSerialize for usize {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for usize {
const TYPE: TdfType = TdfType::VarInt;
}
impl TdfDeserializeOwned for isize {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let value = usize::deserialize_owned(r)?;
Ok(value as isize)
}
}
impl TdfSerializeOwned for isize {
#[inline]
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
(self as usize).serialize_owned(w);
}
}
impl TdfSerialize for isize {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for isize {
const TYPE: TdfType = TdfType::VarInt;
}
#[cfg(test)]
mod test {
use crate::{
reader::TdfDeserializer,
types::{TdfDeserializeOwned, TdfSerialize},
};
#[test]
fn test_unsigned_encoding() {
let mut w = Vec::new();
let values: &[(u64, &[u8])] = &[
(0, &[0]),
(5, &[5]),
(128, &[128, 2]),
(256, &[128, 4]),
(512, &[128, 8]),
(321, &[129, 5]),
(2048, &[128, 32]),
(4096, &[128, 64]),
(4632, &[152, 72]),
(8192, &[128, 128, 1]),
(16384, &[128, 128, 2]),
(32768, &[128, 128, 4]),
(65536, &[128, 128, 8]),
(4294967296, &[128, 128, 128, 128, 32]),
(
9223372036854776000,
&[128, 131, 128, 128, 128, 128, 128, 128, 128, 2],
),
];
for (value, expected) in values {
value.serialize(&mut w);
assert_eq!(&w, expected);
let mut r = TdfDeserializer::new(&w);
let read_value = u64::deserialize_owned(&mut r).unwrap();
assert_eq!(read_value, *value);
w.clear();
}
}
#[test]
fn test_signed_encoding() {
let mut w = Vec::new();
let values: &[(i64, &[u8])] = &[
(-0, &[0]),
(-5, &[187, 255, 255, 255, 255, 255, 255, 255, 255, 3]),
(-128, &[128, 254, 255, 255, 255, 255, 255, 255, 255, 3]),
(-256, &[128, 252, 255, 255, 255, 255, 255, 255, 255, 3]),
(-512, &[128, 248, 255, 255, 255, 255, 255, 255, 255, 3]),
(-321, &[191, 250, 255, 255, 255, 255, 255, 255, 255, 3]),
(-2048, &[128, 224, 255, 255, 255, 255, 255, 255, 255, 3]),
(-4096, &[128, 192, 255, 255, 255, 255, 255, 255, 255, 3]),
(-4632, &[168, 183, 255, 255, 255, 255, 255, 255, 255, 3]),
(-8192, &[128, 128, 255, 255, 255, 255, 255, 255, 255, 3]),
(-16384, &[128, 128, 254, 255, 255, 255, 255, 255, 255, 3]),
(-32768, &[128, 128, 252, 255, 255, 255, 255, 255, 255, 3]),
(-65536, &[128, 128, 248, 255, 255, 255, 255, 255, 255, 3]),
(
-4294967296,
&[128, 128, 128, 128, 224, 255, 255, 255, 255, 3],
),
(
-9223372036854775000,
&[168, 140, 128, 128, 128, 128, 128, 128, 128, 2],
),
];
for (value, expected) in values {
value.serialize(&mut w);
assert_eq!(&w, expected);
let mut r = TdfDeserializer::new(&w);
let read_value = i64::deserialize_owned(&mut r).unwrap();
assert_eq!(read_value, *value);
w.clear();
}
}
}
}
pub mod string {
use super::Blob;
use super::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped};
use crate::{
error::{DecodeError, DecodeResult},
reader::TdfDeserializer,
tag::TdfType,
writer::TdfSerializer,
};
use std::borrow::Cow;
pub fn write_empty_str<S: TdfSerializer>(w: &mut S) {
w.write_slice(&[1, 0]);
}
impl<'de> TdfDeserialize<'de> for &'de str {
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let bytes: &'de [u8] = Blob::deserialize_raw(r)?;
let text: &'de str =
std::str::from_utf8(bytes).map_err(DecodeError::InvalidUtf8Value)?;
if text.is_empty() {
return Err(DecodeError::Other("String value has zero length"));
}
Ok(&text[..text.len() - 1])
}
}
impl TdfSerialize for &str {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
let bytes = self.as_bytes();
let needs_terminator = !matches!(bytes.last(), Some(0));
let mut length = bytes.len();
if needs_terminator {
length += 1;
}
length.serialize_owned(w);
w.write_slice(bytes);
if needs_terminator {
w.write_byte(0);
}
}
}
impl TdfTyped for &str {
const TYPE: TdfType = TdfType::String;
}
impl TdfDeserializeOwned for String {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let bytes: &[u8] = Blob::deserialize_raw(r)?;
let text: Cow<str> = String::from_utf8_lossy(bytes);
let mut text: String = text.to_string();
text.pop();
Ok(text)
}
}
impl TdfSerialize for String {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
self.as_str().serialize(w);
}
}
impl TdfTyped for String {
const TYPE: TdfType = TdfType::String;
}
impl<'de> TdfDeserialize<'de> for Cow<'de, str> {
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let value: &'de str = <&str>::deserialize(r)?;
Ok(Cow::Borrowed(value))
}
}
impl TdfSerialize for Cow<'_, str> {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
match self {
Cow::Borrowed(value) => value.serialize(w),
Cow::Owned(value) => value.serialize(w),
}
}
}
impl TdfTyped for Cow<'_, str> {
const TYPE: TdfType = TdfType::String;
}
#[cfg(test)]
mod test {
use crate::{serialize_vec, Blob, TdfDeserialize, TdfDeserializer, TdfSerialize};
#[test]
fn test_str_serialize() {
let values = &[
("My example string", "My example string\0"),
("Test", "Test\0"),
("", "\0"),
("A", "A\0"),
];
let mut w = Vec::new();
for (value, expected) in values {
value.serialize(&mut w);
let expected_len = value.len() + 1;
let length_bytes = serialize_vec(&expected_len);
assert!(w.starts_with(&length_bytes));
assert!(w.ends_with(&[0]));
let mut r = TdfDeserializer::new(&w);
let str_bytes = Blob::deserialize_raw(&mut r).unwrap();
assert_eq!(expected.as_bytes(), str_bytes);
w.clear();
}
}
#[test]
fn test_str_deserialize() {
let values = &["My example string", "Test", "", "A"];
let mut w = Vec::new();
for value in values {
value.serialize(&mut w);
let mut r = TdfDeserializer::new(&w);
let str = <&str>::deserialize(&mut r).unwrap();
assert_eq!(str, *value);
r.cursor = 0;
let str = String::deserialize(&mut r).unwrap();
assert_eq!(str.as_str(), *value);
w.clear();
}
}
}
}
pub mod blob {
use super::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
};
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Blob<'de>(pub &'de [u8]);
impl AsRef<[u8]> for Blob<'_> {
fn as_ref(&self) -> &[u8] {
self.0
}
}
impl Blob<'_> {
pub fn serialize_raw<S: TdfSerializer>(w: &mut S, slice: &[u8]) {
slice.len().serialize_owned(w);
w.write_slice(slice);
}
pub fn deserialize_raw<'de>(r: &mut TdfDeserializer<'de>) -> DecodeResult<&'de [u8]> {
let length = usize::deserialize_owned(r)?;
let bytes = r.read_bytes(length)?;
Ok(bytes)
}
pub fn skip(r: &mut TdfDeserializer) -> DecodeResult<()> {
let length: usize = usize::deserialize_owned(r)?;
r.skip_length(length)
}
}
impl<'de> TdfDeserialize<'de> for Blob<'de> {
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let bytes = Self::deserialize_raw(r)?;
Ok(Blob(bytes))
}
}
impl TdfSerialize for Blob<'_> {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
Self::serialize_raw(w, self.0)
}
}
impl TdfTyped for Blob<'_> {
const TYPE: TdfType = TdfType::Blob;
}
pub struct OwnedBlob(pub Vec<u8>);
impl TdfDeserializeOwned for OwnedBlob {
fn deserialize_owned(r: &mut TdfDeserializer<'_>) -> DecodeResult<Self> {
let blob = Blob::deserialize_raw(r)?;
Ok(Self(blob.to_vec()))
}
}
impl TdfSerialize for OwnedBlob {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
Blob::serialize_raw(w, &self.0);
}
}
impl TdfTyped for OwnedBlob {
const TYPE: TdfType = TdfType::Blob;
}
}
pub mod list {
use super::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped};
use crate::{
error::{DecodeError, DecodeResult},
reader::TdfDeserializer,
tag::TdfType,
writer::TdfSerializer,
};
pub fn skip_list(r: &mut TdfDeserializer) -> DecodeResult<()> {
let ty: TdfType = TdfType::deserialize_owned(r)?;
let length: usize = usize::deserialize_owned(r)?;
for _ in 0..length {
ty.skip(r, true)?;
}
Ok(())
}
pub fn serialize_list_header<S: TdfSerializer>(w: &mut S, ty: TdfType, length: usize) {
ty.serialize_owned(w);
length.serialize_owned(w);
}
impl<'de, C> TdfDeserialize<'de> for Vec<C>
where
C: TdfDeserialize<'de> + TdfTyped,
{
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let value_type = TdfType::deserialize_owned(r)?;
if value_type != C::TYPE {
return Err(DecodeError::InvalidType {
expected: C::TYPE,
actual: value_type,
});
}
let length = usize::deserialize_owned(r)?;
let mut values = Vec::with_capacity(length);
for _ in 0..length {
values.push(C::deserialize(r)?);
}
Ok(values)
}
}
impl<V> TdfSerialize for Vec<V>
where
V: TdfSerialize + TdfTyped,
{
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
self.as_slice().serialize(w)
}
}
impl<V> TdfTyped for Vec<V> {
const TYPE: TdfType = TdfType::List;
}
impl<V> TdfSerialize for &[V]
where
V: TdfSerialize + TdfTyped,
{
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
serialize_list_header(w, V::TYPE, self.len());
self.iter().for_each(|value| value.serialize(w));
}
}
impl<C> TdfTyped for &[C]
where
C: TdfSerialize + TdfTyped,
{
const TYPE: TdfType = TdfType::List;
}
}
pub mod map {
use super::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped};
use std::{
borrow::Borrow,
fmt::Debug,
ops::{Bound, Index, IndexMut, RangeBounds},
};
use crate::{
error::{DecodeError, DecodeResult},
reader::TdfDeserializer,
tag::TdfType,
writer::TdfSerializer,
};
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TdfMap<K, V> {
data: Vec<(K, V)>,
}
impl<K, V> Default for TdfMap<K, V> {
#[inline]
fn default() -> TdfMap<K, V> {
TdfMap { data: Vec::new() }
}
}
impl<K, V> TdfMap<K, V> {
#[inline]
pub const fn new() -> TdfMap<K, V> {
TdfMap { data: Vec::new() }
}
#[inline]
pub fn with_capacity(cap: usize) -> TdfMap<K, V> {
TdfMap {
data: Vec::with_capacity(cap),
}
}
pub fn into_inner(self) -> Vec<(K, V)> {
self.data
}
}
impl<K: Ord, V> TdfMap<K, V> {
#[inline]
pub fn from_presorted_elements(elements: Vec<(K, V)>) -> TdfMap<K, V> {
TdfMap { data: elements }
}
#[inline]
pub fn insert(&mut self, key: K, mut value: V) -> Option<V> {
match self.lookup_index_for(&key) {
Ok(index) => {
let slot = unsafe { self.data.get_unchecked_mut(index) };
std::mem::swap(&mut slot.1, &mut value);
Some(value)
}
Err(index) => {
self.data.insert(index, (key, value));
None
}
}
}
#[inline]
pub fn remove(&mut self, key: &K) -> Option<V> {
match self.lookup_index_for(key) {
Ok(index) => Some(self.data.remove(index).1),
Err(_) => None,
}
}
#[inline]
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
match self.lookup_index_for(key) {
Ok(index) => unsafe { Some(&self.data.get_unchecked(index).1) },
Err(_) => None,
}
}
#[inline]
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
match self.lookup_index_for(key) {
Ok(index) => unsafe { Some(&mut self.data.get_unchecked_mut(index).1) },
Err(_) => None,
}
}
#[inline]
pub fn get_mut_or_insert_default(&mut self, key: K) -> &mut V
where
K: Eq,
V: Default,
{
let index = match self.lookup_index_for(&key) {
Ok(index) => index,
Err(index) => {
self.data.insert(index, (key, V::default()));
index
}
};
unsafe { &mut self.data.get_unchecked_mut(index).1 }
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
}
#[inline]
pub fn iter(&self) -> std::slice::Iter<'_, (K, V)> {
self.data.iter()
}
#[inline]
pub fn keys(&self) -> impl Iterator<Item = &K> + ExactSizeIterator + DoubleEndedIterator {
self.data.iter().map(|(k, _)| k)
}
#[inline]
pub fn values(&self) -> impl Iterator<Item = &V> + ExactSizeIterator + DoubleEndedIterator {
self.data.iter().map(|(_, v)| v)
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn range<R>(&self, range: R) -> &[(K, V)]
where
R: RangeBounds<K>,
{
let (start, end) = self.range_slice_indices(range);
&self.data[start..end]
}
#[inline]
pub fn remove_range<R>(&mut self, range: R)
where
R: RangeBounds<K>,
{
let (start, end) = self.range_slice_indices(range);
self.data.splice(start..end, std::iter::empty());
}
#[inline]
pub fn offset_keys<F>(&mut self, f: F)
where
F: Fn(&mut K),
{
self.data.iter_mut().map(|(k, _)| k).for_each(f);
}
#[inline]
pub fn insert_presorted(&mut self, elements: Vec<(K, V)>) {
if elements.is_empty() {
return;
}
let start_index = self.lookup_index_for(&elements[0].0);
let elements = match start_index {
Ok(index) => {
let mut elements = elements.into_iter();
self.data[index] = elements.next().unwrap();
elements
}
Err(index) => {
if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 {
self.data.splice(index..index, elements);
return;
}
let mut elements = elements.into_iter();
self.data.insert(index, elements.next().unwrap());
elements
}
};
for (k, v) in elements {
self.insert(k, v);
}
}
#[inline(always)]
fn lookup_index_for<Q>(&self, key: &Q) -> Result<usize, usize>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.data.binary_search_by(|(x, _)| x.borrow().cmp(key))
}
#[inline]
fn range_slice_indices<R>(&self, range: R) -> (usize, usize)
where
R: RangeBounds<K>,
{
let start = match range.start_bound() {
Bound::Included(k) => match self.lookup_index_for(k) {
Ok(index) | Err(index) => index,
},
Bound::Excluded(k) => match self.lookup_index_for(k) {
Ok(index) => index + 1,
Err(index) => index,
},
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(k) => match self.lookup_index_for(k) {
Ok(index) => index + 1,
Err(index) => index,
},
Bound::Excluded(k) => match self.lookup_index_for(k) {
Ok(index) | Err(index) => index,
},
Bound::Unbounded => self.data.len(),
};
(start, end)
}
#[inline]
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.get(key).is_some()
}
}
impl<K: Ord, V> IntoIterator for TdfMap<K, V> {
type Item = (K, V);
type IntoIter = std::vec::IntoIter<(K, V)>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl<'a, K, Q, V> Index<&'a Q> for TdfMap<K, V>
where
K: Ord + Borrow<Q>,
Q: Ord + ?Sized,
{
type Output = V;
fn index(&self, key: &Q) -> &Self::Output {
self.get(key).expect("no entry found for key")
}
}
impl<'a, K, Q, V> IndexMut<&'a Q> for TdfMap<K, V>
where
K: Ord + Borrow<Q>,
Q: Ord + ?Sized,
{
fn index_mut(&mut self, key: &Q) -> &mut Self::Output {
self.get_mut(key).expect("no entry found for key")
}
}
impl<K: Ord, V> FromIterator<(K, V)> for TdfMap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut data: Vec<(K, V)> = iter.into_iter().collect();
data.sort_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2));
data.dedup_by(|(k1, _), (k2, _)| k1 == k2);
TdfMap { data }
}
}
impl<K: Debug, V: Debug> Debug for TdfMap<K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_map()
.entries(self.data.iter().map(|(a, b)| (a, b)))
.finish()
}
}
pub fn deserialize_map_header(
r: &mut TdfDeserializer,
) -> DecodeResult<(TdfType, TdfType, usize)> {
let key_type: TdfType = TdfType::deserialize_owned(r)?;
let value_type: TdfType = TdfType::deserialize_owned(r)?;
let length = usize::deserialize_owned(r)?;
Ok((key_type, value_type, length))
}
pub fn serialize_map_header<S: TdfSerializer>(
w: &mut S,
key_type: TdfType,
value_type: TdfType,
length: usize,
) {
key_type.serialize_owned(w);
value_type.serialize_owned(w);
length.serialize_owned(w);
}
pub fn skip_map(r: &mut TdfDeserializer) -> DecodeResult<()> {
let (key_ty, value_ty, length) = deserialize_map_header(r)?;
for _ in 0..length {
key_ty.skip(r, true)?;
value_ty.skip(r, true)?;
}
Ok(())
}
impl<'de, K, V> TdfDeserialize<'de> for TdfMap<K, V>
where
K: TdfDeserialize<'de> + TdfTyped + Ord,
V: TdfDeserialize<'de> + TdfTyped,
{
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let (key_ty, value_ty, length) = deserialize_map_header(r)?;
if key_ty != K::TYPE {
return Err(DecodeError::InvalidType {
expected: K::TYPE,
actual: key_ty,
});
}
if value_ty != V::TYPE {
return Err(DecodeError::InvalidType {
expected: V::TYPE,
actual: value_ty,
});
}
let mut map: TdfMap<K, V> = TdfMap::with_capacity(length);
for _ in 0..length {
let key: K = K::deserialize(r)?;
let value: V = V::deserialize(r)?;
map.insert(key, value);
}
Ok(map)
}
}
impl<K, V> TdfSerialize for TdfMap<K, V>
where
K: TdfSerialize + TdfTyped + Ord,
V: TdfSerialize + TdfTyped,
{
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
serialize_map_header(w, K::TYPE, V::TYPE, self.len());
self.data.iter().for_each(|(key, value)| {
key.serialize(w);
value.serialize(w);
});
}
}
impl<K, V> TdfTyped for TdfMap<K, V> {
const TYPE: TdfType = TdfType::Map;
}
#[cfg(test)]
mod test {
use crate::TdfMap;
#[test]
fn test_insert_and_iter() {
let mut map: TdfMap<i32, i32> = TdfMap::new();
let mut expected = Vec::new();
for x in 0..100 {
assert_eq!(map.iter().cloned().collect::<Vec<_>>(), expected);
let x = 1000 - x * 2;
map.insert(x, x);
expected.insert(0, (x, x));
}
}
#[test]
fn test_get_and_index() {
let mut map: TdfMap<i32, i32> = TdfMap::new();
let mut expected = Vec::new();
for x in 0..100 {
let x = 1000 - x;
if x & 1 == 0 {
map.insert(x, x);
}
expected.push(x);
}
for mut x in expected {
if x & 1 == 0 {
assert_eq!(map.get(&x), Some(&x));
assert_eq!(map.get_mut(&x), Some(&mut x));
assert_eq!(map[&x], x);
assert_eq!(&mut map[&x], &mut x);
} else {
assert_eq!(map.get(&x), None);
assert_eq!(map.get_mut(&x), None);
}
}
}
#[test]
fn test_range() {
let mut map = TdfMap::new();
map.insert(1, 1);
map.insert(3, 3);
map.insert(6, 6);
map.insert(9, 9);
let keys = |s: &[(_, _)]| s.iter().map(|e| e.0).collect::<Vec<u32>>();
for start in 0..11 {
for end in 0..11 {
if end < start {
continue;
}
let mut expected = vec![1, 3, 6, 9];
expected.retain(|&x| x >= start && x < end);
assert_eq!(
keys(map.range(start..end)),
expected,
"range = {}..{}",
start,
end
);
}
}
}
#[test]
fn test_offset_keys() {
let mut map = TdfMap::new();
map.insert(1, 1);
map.insert(3, 3);
map.insert(6, 6);
map.offset_keys(|k| *k += 1);
let mut expected = TdfMap::new();
expected.insert(2, 1);
expected.insert(4, 3);
expected.insert(7, 6);
assert_eq!(map, expected);
}
fn keys(s: TdfMap<u32, u32>) -> Vec<u32> {
s.into_iter().map(|(k, _)| k).collect::<Vec<u32>>()
}
fn elements(s: TdfMap<u32, u32>) -> Vec<(u32, u32)> {
s.into_iter().collect::<Vec<(u32, u32)>>()
}
#[test]
fn test_remove_range() {
let mut map = TdfMap::new();
map.insert(1, 1);
map.insert(3, 3);
map.insert(6, 6);
map.insert(9, 9);
for start in 0..11 {
for end in 0..11 {
if end < start {
continue;
}
let mut expected = vec![1, 3, 6, 9];
expected.retain(|&x| x < start || x >= end);
let mut map = map.clone();
map.remove_range(start..end);
assert_eq!(keys(map), expected, "range = {}..{}", start, end);
}
}
}
#[test]
fn test_remove() {
let mut map = TdfMap::new();
let mut expected = Vec::new();
for x in 0..10 {
map.insert(x, x);
expected.push((x, x));
}
for x in 0..10 {
let mut map = map.clone();
let mut expected = expected.clone();
assert_eq!(map.remove(&x), Some(x));
expected.remove(x as usize);
assert_eq!(map.iter().cloned().collect::<Vec<_>>(), expected);
}
}
#[test]
fn test_insert_presorted_non_overlapping() {
let mut map = TdfMap::new();
map.insert(2, 0);
map.insert(8, 0);
map.insert_presorted(vec![(3, 0), (7, 0)]);
let expected = vec![2, 3, 7, 8];
assert_eq!(keys(map), expected);
}
#[test]
fn test_insert_presorted_first_elem_equal() {
let mut map = TdfMap::new();
map.insert(2, 2);
map.insert(8, 8);
map.insert_presorted(vec![(2, 0), (7, 7)]);
let expected = vec![(2, 0), (7, 7), (8, 8)];
assert_eq!(elements(map), expected);
}
#[test]
fn test_insert_presorted_last_elem_equal() {
let mut map = TdfMap::new();
map.insert(2, 2);
map.insert(8, 8);
map.insert_presorted(vec![(3, 3), (8, 0)]);
let expected = vec![(2, 2), (3, 3), (8, 0)];
assert_eq!(elements(map), expected);
}
#[test]
fn test_insert_presorted_shuffle() {
let mut map = TdfMap::new();
map.insert(2, 2);
map.insert(7, 7);
map.insert_presorted(vec![(1, 1), (3, 3), (8, 8)]);
let expected = vec![(1, 1), (2, 2), (3, 3), (7, 7), (8, 8)];
assert_eq!(elements(map), expected);
}
#[test]
fn test_insert_presorted_at_end() {
let mut map = TdfMap::new();
map.insert(1, 1);
map.insert(2, 2);
map.insert_presorted(vec![(3, 3), (8, 8)]);
let expected = vec![(1, 1), (2, 2), (3, 3), (8, 8)];
assert_eq!(elements(map), expected);
}
}
}
pub mod tagged_union {
use super::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfTyped};
use crate::{
error::{DecodeError, DecodeResult},
reader::TdfDeserializer,
tag::{Tag, Tagged, TdfType},
writer::TdfSerializer,
GroupSlice,
};
#[derive(Debug, PartialEq, Eq)]
pub enum TaggedUnion<V> {
Set {
key: u8,
tag: Tag,
value: V,
},
Unset,
}
pub const TAGGED_UNSET_KEY: u8 = 0x7F;
impl<V> TaggedUnion<V> {
pub fn is_set(&self) -> bool {
matches!(self, Self::Set { .. })
}
pub fn is_unset(&self) -> bool {
matches!(self, Self::Unset)
}
pub fn unwrap(self) -> V {
match self {
Self::Unset => panic!("Attempted to unwrap unset union"),
Self::Set { value, .. } => value,
}
}
}
impl<V> From<TaggedUnion<V>> for Option<V> {
fn from(value: TaggedUnion<V>) -> Self {
match value {
TaggedUnion::Set { value, .. } => Some(value),
TaggedUnion::Unset => None,
}
}
}
impl<V> TdfTyped for TaggedUnion<V> {
const TYPE: TdfType = TdfType::TaggedUnion;
}
pub fn skip_tagged_union(r: &mut TdfDeserializer, heat_compat: bool) -> DecodeResult<()> {
let ty = r.read_byte()?;
if ty != TAGGED_UNSET_KEY {
if heat_compat {
GroupSlice::skip(r, false)?;
} else {
Tagged::skip(r)?;
}
}
Ok(())
}
impl<'de, V> TdfDeserialize<'de> for TaggedUnion<V>
where
V: TdfDeserialize<'de> + TdfTyped,
{
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let key = r.read_byte()?;
if key == TAGGED_UNSET_KEY {
return Ok(TaggedUnion::Unset);
}
let tag = Tagged::deserialize_owned(r)?;
let expected_type = V::TYPE;
let actual_type = tag.ty;
if actual_type != expected_type {
return Err(DecodeError::InvalidType {
expected: expected_type,
actual: actual_type,
});
}
let value = V::deserialize(r)?;
Ok(TaggedUnion::Set {
key,
tag: tag.tag,
value,
})
}
}
impl<V> TdfSerialize for TaggedUnion<V>
where
V: TdfSerialize + TdfTyped,
{
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
match self {
TaggedUnion::Set { key, tag, value } => {
w.write_byte(*key);
Tagged::serialize_raw(w, &tag.0, V::TYPE);
value.serialize(w);
}
TaggedUnion::Unset => w.write_byte(TAGGED_UNSET_KEY),
}
}
}
}
pub mod var_int_list {
use super::{TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
};
use super::var_int::skip_var_int;
#[derive(Debug, PartialEq, Eq, Default, Clone)]
pub struct VarIntList(pub Vec<u64>);
impl VarIntList {
pub const fn new() -> Self {
Self(Vec::new())
}
pub fn into_inner(self) -> Vec<u64> {
self.0
}
pub fn skip(r: &mut TdfDeserializer) -> DecodeResult<()> {
let length: usize = usize::deserialize_owned(r)?;
for _ in 0..length {
skip_var_int(r)?;
}
Ok(())
}
}
impl From<Vec<u64>> for VarIntList {
fn from(value: Vec<u64>) -> Self {
Self(value)
}
}
impl AsRef<[u64]> for VarIntList {
fn as_ref(&self) -> &[u64] {
self.0.as_ref()
}
}
impl TdfDeserializeOwned for VarIntList {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let length = usize::deserialize_owned(r)?;
let mut out = Vec::with_capacity(length);
for _ in 0..length {
out.push(u64::deserialize_owned(r)?);
}
Ok(VarIntList(out))
}
}
impl TdfSerialize for VarIntList {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
self.0.len().serialize_owned(w);
self.0
.iter()
.copied()
.for_each(|value| value.serialize_owned(w));
}
}
impl TdfTyped for VarIntList {
const TYPE: TdfType = TdfType::VarIntList;
}
}
pub mod object_type {
use super::{
var_int::skip_var_int, TdfDeserializeOwned, TdfSerialize, TdfSerializeOwned, TdfTyped,
};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ObjectType {
pub component: u16,
pub ty: u16,
}
impl ObjectType {
#[inline]
pub const fn zero() -> Self {
Self::new(0, 0)
}
pub const fn new(component: u16, ty: u16) -> Self {
Self { component, ty }
}
pub fn skip(r: &mut TdfDeserializer) -> DecodeResult<()> {
skip_var_int(r)?;
skip_var_int(r)
}
}
impl TdfDeserializeOwned for ObjectType {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let component = u16::deserialize_owned(r)?;
let ty = u16::deserialize_owned(r)?;
Ok(Self { component, ty })
}
}
impl TdfSerialize for ObjectType {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
self.component.serialize_owned(w);
self.ty.serialize_owned(w);
}
}
impl TdfTyped for ObjectType {
const TYPE: TdfType = TdfType::ObjectType;
}
#[cfg(test)]
mod test {
use crate::{
reader::TdfDeserializer,
types::{TdfDeserialize, TdfSerialize},
};
use super::ObjectType;
#[test]
fn test_encode_object_id() {
let mut w = Vec::new();
let object_type = ObjectType {
component: 30722,
ty: 1,
};
object_type.serialize(&mut w);
let mut r = TdfDeserializer::new(&w);
let value = ObjectType::deserialize(&mut r).unwrap();
assert_eq!(object_type, value);
let expected = &[
130, 224, 3, 1, ];
assert_eq!(&r.buffer, expected)
}
}
}
pub mod object_id {
use super::{
object_type::ObjectType, var_int::skip_var_int, TdfDeserializeOwned, TdfSerialize,
TdfSerializeOwned, TdfTyped,
};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ObjectId {
pub ty: ObjectType,
pub id: u64,
}
impl ObjectId {
#[inline]
pub const fn zero() -> Self {
Self::new(ObjectType::zero(), 0)
}
pub const fn new(ty: ObjectType, id: u64) -> Self {
Self { ty, id }
}
pub const fn new_raw(component: u16, ty: u16, id: u64) -> Self {
Self {
ty: ObjectType { component, ty },
id,
}
}
pub fn skip(r: &mut TdfDeserializer) -> DecodeResult<()> {
ObjectType::skip(r)?;
skip_var_int(r)
}
}
impl TdfDeserializeOwned for ObjectId {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let ty = ObjectType::deserialize_owned(r)?;
let id = u64::deserialize_owned(r)?;
Ok(Self { ty, id })
}
}
impl TdfSerialize for ObjectId {
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
self.ty.serialize(w);
self.id.serialize_owned(w);
}
}
impl TdfTyped for ObjectId {
const TYPE: TdfType = TdfType::ObjectId;
}
#[cfg(test)]
mod test {
use crate::{
reader::TdfDeserializer,
types::object_type::ObjectType,
types::{TdfDeserialize, TdfSerialize},
};
use super::ObjectId;
#[test]
fn test_encode_object_id() {
let mut w = Vec::new();
let object_id = ObjectId {
ty: ObjectType {
component: 30722,
ty: 1,
},
id: 0x0000012,
};
object_id.serialize(&mut w);
let mut r = TdfDeserializer::new(&w);
let value = ObjectId::deserialize(&mut r).unwrap();
assert_eq!(object_id.ty, value.ty);
assert_eq!(object_id.id, value.id);
let expected = &[
130, 224, 3, 1, 18, ];
assert_eq!(&r.buffer, expected)
}
}
}
pub mod float {
use super::{TdfDeserializeOwned, TdfSerializeOwned, TdfTyped};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, writer::TdfSerializer,
TdfSerialize,
};
#[inline]
pub fn skip_f32(r: &mut TdfDeserializer) -> DecodeResult<()> {
r.skip_length(4)
}
impl TdfDeserializeOwned for f32 {
fn deserialize_owned(r: &mut TdfDeserializer) -> DecodeResult<Self> {
let bytes: [u8; 4] = r.read_fixed()?;
Ok(f32::from_be_bytes(bytes))
}
}
impl TdfSerializeOwned for f32 {
fn serialize_owned<S: TdfSerializer>(self, w: &mut S) {
let bytes: [u8; 4] = self.to_be_bytes();
w.write_slice(&bytes);
}
}
impl TdfSerialize for f32 {
#[inline]
fn serialize<S: TdfSerializer>(&self, w: &mut S) {
(*self).serialize_owned(w)
}
}
impl TdfTyped for f32 {
const TYPE: TdfType = TdfType::Float;
}
#[cfg(test)]
mod test {
use crate::{reader::TdfDeserializer, types::TdfDeserializeOwned, types::TdfSerialize};
#[test]
fn test_float_encoding() {
let data: &[(f32, [u8; 4])] = &[
(123.0, [66, 246, 0, 0]),
(254.0, [67, 126, 0, 0]),
(1.0, [63, 128, 0, 0]),
(-3.0, [192, 64, 0, 0]),
];
let mut w = Vec::new();
for (value, expected) in data {
value.serialize(&mut w);
assert_eq!(&w, expected);
let mut r = TdfDeserializer::new(&w);
let read_value = f32::deserialize_owned(&mut r).unwrap();
assert_eq!(read_value, *value);
w.clear();
}
}
}
}
pub mod generic {
use super::{var_int::skip_var_int, TdfTyped};
use crate::{
error::DecodeResult, reader::TdfDeserializer, tag::TdfType, GroupSlice, TdfDeserializeOwned,
};
pub struct TdfGeneric {
pub inner: Option<TdfGenericInner>,
}
impl TdfDeserializeOwned for TdfGeneric {
fn deserialize_owned(r: &mut TdfDeserializer<'_>) -> DecodeResult<Self> {
let present: bool = bool::deserialize_owned(r)?;
if !present {
return Ok(Self { inner: None });
}
let tdf_id: u64 = u64::deserialize_owned(r)?;
_ = r.read_byte()?;
let ty: TdfType = TdfType::deserialize_owned(r)?;
let value = match ty {
TdfType::VarInt => TdfGenericValue::Int(usize::deserialize_owned(r)?),
TdfType::String => TdfGenericValue::String(String::deserialize_owned(r)?),
ty => {
ty.skip(r, false)?;
TdfGenericValue::Other
}
};
GroupSlice::deserialize_group_end(r)?;
Ok(Self {
inner: Some(TdfGenericInner { tdf_id, value }),
})
}
}
impl TdfGeneric {
pub fn skip(r: &mut TdfDeserializer) -> DecodeResult<()> {
let present: bool = bool::deserialize_owned(r)?;
if !present {
return Ok(());
}
skip_var_int(r)?;
let ty = TdfType::deserialize_owned(r)?;
ty.skip(r, false)?;
GroupSlice::deserialize_group_end(r)?;
Ok(())
}
}
pub struct TdfGenericInner {
pub tdf_id: u64,
pub value: TdfGenericValue,
}
pub enum TdfGenericValue {
Int(usize),
String(String),
Other,
}
impl TdfTyped for TdfGeneric {
const TYPE: TdfType = TdfType::Generic;
}
}
pub mod group {
use super::{tagged_union::skip_tagged_union, TdfDeserialize};
use crate::{error::DecodeResult, reader::TdfDeserializer, tag::Tagged};
pub struct GroupSlice<'de> {
pub data: &'de [u8],
}
impl GroupSlice<'_> {
pub fn deserialize_group_end(r: &mut TdfDeserializer) -> DecodeResult<bool> {
let is_end = r.read_byte()? == 0;
if !is_end {
r.step_back();
}
Ok(is_end)
}
#[inline]
pub fn deserialize_content<'de, A>(
r: &mut TdfDeserializer<'de>,
mut action: A,
) -> DecodeResult<&'de [u8]>
where
A: FnMut(&mut TdfDeserializer<'de>) -> DecodeResult<()>,
{
let start = r.cursor;
loop {
let is_end = Self::deserialize_group_end(r)?;
if is_end {
break;
}
action(r)?;
}
let end = r.cursor - 1;
let data = &r.buffer[start..end];
Ok(data)
}
#[inline]
pub fn deserialize_content_skip<'de>(
r: &mut TdfDeserializer<'de>,
) -> DecodeResult<&'de [u8]> {
Self::deserialize_content(r, Tagged::skip)
}
pub fn try_validate_group(r: &mut TdfDeserializer) -> bool {
let cursor = r.cursor;
let valid = GroupSlice::deserialize_content_skip(r).is_ok();
r.cursor = cursor;
valid
}
pub fn skip(r: &mut TdfDeserializer, heat_compat: bool) -> DecodeResult<()> {
if heat_compat && !Self::try_validate_group(r) {
return skip_tagged_union(r, true);
}
Self::deserialize_content_skip(r)?;
Ok(())
}
}
impl<'de> TdfDeserialize<'de> for GroupSlice<'de> {
fn deserialize(r: &mut TdfDeserializer<'de>) -> DecodeResult<Self> {
let data = Self::deserialize_content_skip(r)?;
Ok(Self { data })
}
}
}
pub mod extra {
use std::{borrow::Cow, rc::Rc, sync::Arc};
use crate::{TdfDeserialize, TdfDeserializeOwned, TdfSerialize, TdfType, TdfTyped};
impl TdfSerialize for () {
fn serialize<S: crate::TdfSerializer>(&self, _: &mut S) {}
}
impl TdfDeserializeOwned for () {
fn deserialize_owned(_: &mut crate::TdfDeserializer<'_>) -> crate::DecodeResult<Self> {
Ok(())
}
}
impl<T, E> TdfSerialize for Result<T, E>
where
T: TdfSerialize,
E: TdfSerialize,
{
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
match self {
Ok(value) => value.serialize(w),
Err(value) => value.serialize(w),
}
}
}
impl<T> TdfSerialize for Option<T>
where
T: TdfSerialize,
{
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
if let Some(value) = self {
value.serialize(w);
}
}
}
impl<T> TdfSerialize for &T
where
T: TdfSerialize,
{
#[inline]
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
TdfSerialize::serialize(*self, w);
}
}
impl<T> TdfTyped for &T
where
T: TdfTyped,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfSerialize for &mut T
where
T: TdfSerialize,
{
#[inline]
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
TdfSerialize::serialize(*self, w);
}
}
impl<T> TdfTyped for &mut T
where
T: TdfTyped,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfSerialize for Box<T>
where
T: TdfSerialize,
{
#[inline]
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
TdfSerialize::serialize(self.as_ref(), w);
}
}
impl<T> TdfTyped for Box<T>
where
T: TdfTyped,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfSerialize for Rc<T>
where
T: TdfSerialize,
{
#[inline]
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
TdfSerialize::serialize(self.as_ref(), w);
}
}
impl<T> TdfTyped for Rc<T>
where
T: TdfTyped,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfSerialize for Arc<T>
where
T: TdfSerialize,
{
#[inline]
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
TdfSerialize::serialize(self.as_ref(), w);
}
}
impl<T> TdfTyped for Arc<T>
where
T: TdfTyped,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfSerialize for Cow<'_, T>
where
T: TdfSerialize + ToOwned,
T::Owned: TdfSerialize,
{
fn serialize<S: crate::TdfSerializer>(&self, w: &mut S) {
match self {
Cow::Borrowed(value) => (**value).serialize(w),
Cow::Owned(value) => (*value).serialize(w),
};
}
}
impl<T> TdfTyped for Cow<'_, T>
where
T: TdfTyped + ToOwned,
{
const TYPE: TdfType = T::TYPE;
}
impl<T> TdfDeserializeOwned for Box<T>
where
T: for<'de> TdfDeserialize<'de>,
{
#[inline]
fn deserialize_owned(r: &mut crate::TdfDeserializer<'_>) -> crate::DecodeResult<Self> {
T::deserialize(r).map(Box::new)
}
}
impl<T> TdfDeserializeOwned for Rc<T>
where
T: for<'de> TdfDeserialize<'de>,
{
#[inline]
fn deserialize_owned(r: &mut crate::TdfDeserializer<'_>) -> crate::DecodeResult<Self> {
T::deserialize(r).map(Rc::new)
}
}
impl<T> TdfDeserializeOwned for Arc<T>
where
T: for<'de> TdfDeserialize<'de>,
{
#[inline]
fn deserialize_owned(r: &mut crate::TdfDeserializer<'_>) -> crate::DecodeResult<Self> {
T::deserialize(r).map(Arc::new)
}
}
impl<'de, T> TdfDeserialize<'de> for Cow<'de, T>
where
T: ToOwned,
T::Owned: TdfDeserialize<'de>,
{
fn deserialize(r: &mut crate::TdfDeserializer<'de>) -> crate::DecodeResult<Self> {
<T::Owned as TdfDeserialize<'de>>::deserialize(r).map(Cow::Owned)
}
}
}