bencode inspired tight self describing serialization format
errors
bendn 10 days ago
parent cd0183c · commit c307650
-rw-r--r--src/de.rs77
-rw-r--r--src/de/tests.rs3
-rw-r--r--src/error.rs6
-rw-r--r--src/ser.rs49
4 files changed, 64 insertions, 71 deletions
diff --git a/src/de.rs b/src/de.rs
index e1f29d2..8adb30d 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -13,19 +13,8 @@ pub fn from_bytes<'a, T: Deserialize<'a>>(x: &'a [u8]) -> Result<T> {
let mut d = Deserializer { r: x };
T::deserialize(&mut d)
}
-#[test]
-fn de_leb128() {
- use atools::prelude::*;
- dbg!(
- Deserializer {
- r: &[0x80; 18].join(04)
- }
- .leb128()
- .unwrap()
- );
-}
-impl<'de> Deserializer<'de> {
+impl Deserializer<'_> {
pub fn leb128(&mut self) -> Result<u128> {
let mut res = 0u128;
let mut shift = 0;
@@ -35,7 +24,7 @@ impl<'de> Deserializer<'de> {
if shift == 18 && b > 0b11 {
return Err(Error::Overflow);
}
- res |= ((b & 127) as u128)
+ res |= u128::from(b & 127)
.checked_shl(shift * 7)
.ok_or(Error::Overflow)?;
shift += 1;
@@ -55,7 +44,7 @@ impl<'de> Deserializer<'de> {
&& let 0..=1 | 126..=127 = b
{}
- res |= ((b & 127) as u128)
+ res |= u128::from(b & 127)
.checked_shl(shift * 7)
.ok_or(Error::Overflow)?;
shift += 1;
@@ -134,7 +123,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
x if T::UVariant == x => {
self.tag(T::UVariant)?;
self.tag(T::Uint)?;
- visitor.visit_u32(self.leb128()? as _)
+ visitor.visit_u32(self.leb128()?.try_into()?)
}
x if T::TVariant == x => {
self.tag(T::TVariant)?;
@@ -170,7 +159,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
V: Visitor<'de>,
{
self.tag(T::Int)?;
- visitor.visit_i8(self.sleb128()? as _)
+ visitor.visit_i8(self.sleb128()?.try_into()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
@@ -178,7 +167,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
V: Visitor<'de>,
{
self.tag(T::Int)?;
- visitor.visit_i16(self.sleb128()? as _)
+ visitor.visit_i16(self.sleb128()?.try_into()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
@@ -186,7 +175,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
V: Visitor<'de>,
{
self.tag(T::Int)?;
- visitor.visit_i32(self.sleb128()? as _)
+ visitor.visit_i32(self.sleb128()?.try_into()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
@@ -194,7 +183,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
V: Visitor<'de>,
{
self.tag(T::Int)?;
- visitor.visit_i64(self.sleb128()? as _)
+ visitor.visit_i64(self.sleb128()?.try_into()?)
}
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
@@ -210,7 +199,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::Uint)?;
let v = self.leb128()?;
- visitor.visit_u8(v as _)
+ visitor.visit_u8(v.try_into()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
@@ -219,7 +208,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::Uint)?;
let v = self.leb128()?;
- visitor.visit_u16(v as _)
+ visitor.visit_u16(v.try_into()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
@@ -228,7 +217,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::Uint)?;
let v = self.leb128()?;
- visitor.visit_u32(v as _)
+ visitor.visit_u32(v.try_into()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
@@ -237,7 +226,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::Uint)?;
let v = self.leb128()?;
- visitor.visit_u64(v as _)
+ visitor.visit_u64(v.try_into()?)
}
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
@@ -271,7 +260,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::Uint)?;
let v = self.leb128()?;
- visitor.visit_char(char::from_u32(v as _).ok_or(Error::NotChar(v as u32))?)
+ visitor.visit_char(char::from_u32(v.try_into()?).ok_or(Error::NotChar(v.try_into()?))?)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
@@ -288,7 +277,7 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
self.tag(T::String)?;
let len = self.leb128()? as usize;
let v = visitor
- .visit_borrowed_str(str::from_utf8(&self.r.get(..len).ok_or(Error::OOB)?)?);
+ .visit_borrowed_str(str::from_utf8(self.r.get(..len).ok_or(Error::OOB)?)?);
self.r = self.r.get(len..).ok_or(Error::OOB)?;
v
}
@@ -315,8 +304,8 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
{
self.tag(T::String)?;
let len = self.leb128()? as usize;
- let v = visitor.visit_borrowed_bytes(&self.r.get(..len).ok_or(Error::OOB)?);
- self.r = &self.r.get(len..).ok_or(Error::OOB)?;
+ let v = visitor.visit_borrowed_bytes(self.r.get(..len).ok_or(Error::OOB)?);
+ self.r = self.r.get(len..).ok_or(Error::OOB)?;
v
}
@@ -384,13 +373,13 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
self.deserialize_seq(visitor)
}
- fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.tag(T::Map)?;
let len = self.leb128()? as usize;
- _visitor.visit_map(MapAccess { de: self, len })
+ visitor.visit_map(MapAccess { de: self, len })
}
fn deserialize_struct<V>(
@@ -429,11 +418,11 @@ impl<'de> serde::Deserializer<'de> for &mut Deserializer<'de> {
match self.t()? {
x if T::String == x => {
let len = self.leb128()? as usize;
- let v = str::from_utf8(&self.r.get(..len).ok_or(Error::OOB)?)?;
+ let v = str::from_utf8(self.r.get(..len).ok_or(Error::OOB)?)?;
self.r = self.r.get(len..).ok_or(Error::OOB)?;
- visitor.visit_borrowed_str(&v)
+ visitor.visit_borrowed_str(v)
}
- x if T::Uint == x => visitor.visit_u32(self.leb128()? as _),
+ x if T::Uint == x => visitor.visit_u32(self.leb128()?.try_into()?),
x => Err(Error::Expected {
expected: T::String,
found: x,
@@ -460,7 +449,7 @@ impl<'a, 'de> SeqAccess<'a, 'de> {
}
}
-impl<'a, 'de> de::SeqAccess<'de> for SeqAccess<'a, 'de> {
+impl<'de> de::SeqAccess<'de> for SeqAccess<'_, 'de> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
@@ -487,7 +476,7 @@ impl<'a, 'de> EnumAccess<'a, 'de> {
}
}
-impl<'a, 'de> de::EnumAccess<'de> for EnumAccess<'a, 'de> {
+impl<'de> de::EnumAccess<'de> for EnumAccess<'_, 'de> {
type Error = Error;
type Variant = Self;
@@ -500,7 +489,7 @@ impl<'a, 'de> de::EnumAccess<'de> for EnumAccess<'a, 'de> {
}
}
-impl<'a, 'de> de::VariantAccess<'de> for EnumAccess<'a, 'de> {
+impl<'de> de::VariantAccess<'de> for EnumAccess<'_, 'de> {
type Error = Error;
fn unit_variant(self) -> Result<()> {
@@ -518,21 +507,25 @@ impl<'a, 'de> de::VariantAccess<'de> for EnumAccess<'a, 'de> {
where
V: Visitor<'de>,
{
- let x = self.de.leb128()?;
- assert_eq!(x, len as u128);
+ let x = self.de.leb128()? as usize;
+ if x != len {
+ return Err(Error::IncoherentLen(x, len));
+ }
visitor.visit_seq(SeqAccess::new(self.de, len))
}
- fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
- let x = self.de.leb128()?;
- assert_eq!(x, _fields.len() as u128);
+ let x = self.de.leb128()? as usize;
+ if x != fields.len() {
+ return Err(Error::IncoherentLen(x, fields.len()));
+ }
// T::SVariant data follows
visitor.visit_map(MapAccess {
de: self.de,
- len: _fields.len(),
+ len: fields.len(),
})
}
}
@@ -541,7 +534,7 @@ struct MapAccess<'a, 'de> {
de: &'a mut Deserializer<'de>,
len: usize,
}
-impl<'a, 'de> de::MapAccess<'de> for MapAccess<'a, 'de> {
+impl<'de> de::MapAccess<'de> for MapAccess<'_, 'de> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
diff --git a/src/de/tests.rs b/src/de/tests.rs
index 3ecf0d0..daa4fd8 100644
--- a/src/de/tests.rs
+++ b/src/de/tests.rs
@@ -1,7 +1,6 @@
use std::collections::HashMap;
-use serde::{Deserialize, Serialize, de::DeserializeOwned};
-use serde_json::to_value;
+use serde::{Deserialize, Serialize};
use crate::to_bytes;
diff --git a/src/error.rs b/src/error.rs
index 6f70009..7870161 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -32,6 +32,12 @@ pub enum Error {
NotTag(u8),
#[error("out of range")]
Overflow,
+ #[error(
+ "the length provided in the data stream {0} is different from the hint serde provided {1}"
+ )]
+ IncoherentLen(usize, usize),
+ #[error(transparent)]
+ TryFromIntError(#[from] std::num::TryFromIntError),
}
impl serde::ser::Error for Error {
diff --git a/src/ser.rs b/src/ser.rs
index ad4ac8f..e2994a5 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -1,6 +1,6 @@
use crate::error::{Error, Result};
use crate::serde::T;
-use raad::le::*;
+use raad::le::W;
use serde::{Serialize, ser};
use std::io::Write;
@@ -39,23 +39,21 @@ impl<W: std::io::Write> Serializer<W> {
if w == 0 {
self.w.w(n)?;
break;
- } else {
- self.w.w(n | 1 << 7)?;
}
+ self.w.w(n | 1 << 7)?;
}
Ok(())
}
- fn sleb128(&mut self, mut value: i128) -> Result<()> {
+ fn sleb128(&mut self, mut w: i128) -> Result<()> {
loop {
- let n = (value & 127) as u8;
- value >>= 7;
- let sign_bit = (n & 64) != 0;
- if (value == 0 && !sign_bit) || (value == -1 && sign_bit) {
+ let n = (w & 127) as i8;
+ w >>= 7;
+ let sign = (n & 64) != 0;
+ if (w == 0 && !sign) || (w == -1 && sign) {
self.w.w(n)?;
break;
- } else {
- self.w.w(n | 1 << 7)?;
}
+ self.w.w(n | 1 << 7)?;
}
Ok(())
}
@@ -90,7 +88,7 @@ impl<W: std::io::Write> ser::Serializer for &mut Serializer<W> {
// into the output string.
fn serialize_bool(self, v: bool) -> Result<()> {
// println!("serialize bool {v}");
- self.w.w(v as u8)?;
+ self.w.w(u8::from(v))?;
Ok(())
}
@@ -113,7 +111,7 @@ impl<W: std::io::Write> ser::Serializer for &mut Serializer<W> {
fn serialize_i64(self, v: i64) -> Result<()> {
// println!("serialize i64 {v}");
self.t(T::Int)?;
- self.sleb128(v as i128)
+ self.sleb128(v.into())
}
fn serialize_u8(self, v: u8) -> Result<()> {
@@ -254,25 +252,22 @@ impl<W: std::io::Write> ser::Serializer for &mut Serializer<W> {
fn serialize_tuple_variant(
self,
_name: &'static str,
- _variant_index: u32,
+ idx: u32,
_variant: &'static str,
- _len: usize,
+ len: usize,
) -> Result<Self::SerializeTupleVariant> {
- // println!("serialize tuple variant {_variant} of {_name} {_variant_index} {_variant}");
+ // println!("serialize tuple variant {_variant} of {_name} {idx} {_variant}");
self.w.w(T::TVariant as u8)?;
- self.serialize_u32(_variant_index)?;
- self.leb128(_len as u128)?;
- // self.output += "{";
- // variant.serialize(&mut *self)?;
- // self.output += ":[";
+ self.serialize_u32(idx)?;
+ self.leb128(len as u128)?;
Ok(self)
}
// Maps are represented in JSON as `{ K: V, K: V, ... }`.
- fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
self.w.w(T::Map as u8)?;
// println!("{_len:?}");
- self.leb128(_len.ok_or(Error::LenLess)? as u128)?;
+ self.leb128(len.ok_or(Error::LenLess)? as u128)?;
Ok(self)
// Ok(self)
@@ -292,14 +287,14 @@ impl<W: std::io::Write> ser::Serializer for &mut Serializer<W> {
fn serialize_struct_variant(
self,
_name: &'static str,
- _variant_index: u32,
- variant: &'static str,
- _len: usize,
+ idx: u32,
+ _variant: &'static str,
+ len: usize,
) -> Result<Self::SerializeStructVariant> {
// println!("ser struct v {_name} {_variant_index} {variant} {_len}");
self.w.w(T::SVariant as u8)?;
- self.serialize_u32(_variant_index)?;
- self.leb128(_len as u128)?;
+ self.serialize_u32(idx)?;
+ self.leb128(len as u128)?;
Ok(self)
}
}