optimized unpack from slice: no more copying to vec

This commit is contained in:
Sergey Chernov 2023-11-27 23:36:08 +03:00
parent 7428fad29c
commit 8bba1ef943
3 changed files with 19 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "bipack_ru" name = "bipack_ru"
version = "0.3.2" version = "0.3.3"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
description = "binary size-effective format used in Divan smart contracts, wasm bindings, network protocols, etc." description = "binary size-effective format used in Divan smart contracts, wasm bindings, network protocols, etc."

View File

@ -167,7 +167,7 @@ pub struct SliceSource<'a> {
} }
impl<'a> SliceSource<'a> { impl<'a> SliceSource<'a> {
pub fn from(src: &'a [u8]) -> SliceSource { pub fn from(src: &'a [u8]) -> SliceSource<'a> {
SliceSource { data: src, position: 0 } SliceSource { data: src, position: 0 }
} }
} }

View File

@ -2,23 +2,21 @@ use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, V
use serde::de::value::U32Deserializer; use serde::de::value::U32Deserializer;
use serde::Deserialize; use serde::Deserialize;
use crate::bipack_source::{BipackSource, VecSource}; use crate::bipack_source::{BipackSource, SliceSource};
use crate::error::{Error, Result}; use crate::error::{Error, Result};
pub struct Deserializer { pub struct Deserializer<T: BipackSource> {
// This string starts with the input data and characters are truncated off // This string starts with the input data and characters are truncated off
// the beginning as data is parsed. // the beginning as data is parsed.
input: VecSource, input: T,
} }
pub fn from_bytes<'de, T: Deserialize<'de>>(source: &[u8]) -> Result<T> { pub fn from_bytes<'de, T: Deserialize<'de>>(source: &[u8]) -> Result<T> {
let mut des = Deserializer { input: VecSource::from(source.to_vec()) }; let mut des = Deserializer { input: SliceSource::from(&source) };
T::deserialize(&mut des) T::deserialize(&mut des)
} }
impl Deserializer {} impl<'de, 'a, T: BipackSource> de::Deserializer<'de> for &'a mut Deserializer<T> {
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
type Error = Error; type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> { fn deserialize_any<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> where V: Visitor<'de> {
@ -163,7 +161,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer {
} }
} }
impl<'de, 'a> serde::de::EnumAccess<'de> for &'a mut Deserializer { impl<'de, 'a, T: BipackSource> serde::de::EnumAccess<'de> for &'a mut Deserializer<T> {
type Error = Error; type Error = Error;
type Variant = Self; type Variant = Self;
@ -177,7 +175,7 @@ impl<'de, 'a> serde::de::EnumAccess<'de> for &'a mut Deserializer {
} }
} }
impl<'de, 'a> serde::de::VariantAccess<'de> for &'a mut Deserializer { impl<'de, 'a, T: BipackSource> serde::de::VariantAccess<'de> for &'a mut Deserializer<T> {
type Error = Error; type Error = Error;
#[inline] #[inline]
@ -206,13 +204,13 @@ impl<'de, 'a> serde::de::VariantAccess<'de> for &'a mut Deserializer {
} }
struct SimpleSeq<'a> { struct SimpleSeq<'a, T: BipackSource> {
de: &'a mut Deserializer, de: &'a mut Deserializer<T>,
size: usize, size: usize,
} }
impl<'a> SimpleSeq<'a> { impl<'a, T: BipackSource> SimpleSeq<'a, T> {
fn new(de: &'a mut Deserializer, size: usize) -> Self { fn new(de: &'a mut Deserializer<T>, size: usize) -> Self {
SimpleSeq { SimpleSeq {
de, de,
size: size, size: size,
@ -222,12 +220,12 @@ impl<'a> SimpleSeq<'a> {
// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate // `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
// through elements of the sequence. // through elements of the sequence.
impl<'de, 'a> SeqAccess<'de> for SimpleSeq<'a> { impl<'de, 'a, T: BipackSource> SeqAccess<'de> for SimpleSeq<'a, T> {
type Error = Error; type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> fn next_element_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>>
where where
T: DeserializeSeed<'de>, S: DeserializeSeed<'de>,
{ {
if self.size < 1 { if self.size < 1 {
return Ok(None); return Ok(None);
@ -238,12 +236,12 @@ impl<'de, 'a> SeqAccess<'de> for SimpleSeq<'a> {
} }
struct SimpleMap<'a> { struct SimpleMap<'a, T: BipackSource> {
de: &'a mut Deserializer, de: &'a mut Deserializer<T>,
size: usize, size: usize,
} }
impl<'de, 'a> MapAccess<'de> for SimpleMap<'a> { impl<'de, 'a, T: BipackSource> MapAccess<'de> for SimpleMap<'a,T> {
type Error = Error; type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> std::result::Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de> { fn next_key_seed<K>(&mut self, seed: K) -> std::result::Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de> {