From e06d553ed70768f1e8353db0ed40144a62bdc7b4 Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 9 Oct 2023 22:42:53 +0100 Subject: [PATCH] docs, preparing for publication --- src/bipack_sink.rs | 8 +++++++- src/bipack_source.rs | 32 ++++++++++++++++++-------------- src/lib.rs | 7 +++---- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/bipack_sink.rs b/src/bipack_sink.rs index 5731295..31a2edb 100644 --- a/src/bipack_sink.rs +++ b/src/bipack_sink.rs @@ -26,7 +26,13 @@ into_u64!(u8, u16, u32, usize, u64); /// Data sink to encode bipack binary format. /// -/// To implement just override [put_u8] and optionally [put_fixed_bytes] +/// To implement just override [put_u8] and optionally [put_fixed_bytes]. +/// +/// Note that the sink is not returning errors, unlike [crate::bipack_source::BipackSource]. +/// It is supposed that the sink has unlimited +/// size for the context of data it is used for. This is practical. For the case of overflow-aware +/// sink you can create one that ignores extra data when overflow is detected and report it +/// somehow, but for encoding it does not worth effort (data size could be estimated in advance). pub trait BipackSink { fn put_u8(self: &mut Self, data: u8); diff --git a/src/bipack_source.rs b/src/bipack_source.rs index a516740..35c8582 100644 --- a/src/bipack_source.rs +++ b/src/bipack_source.rs @@ -4,7 +4,7 @@ use std::string::FromUtf8Error; use crate::bipack_source::BipackError::NoDataError; /// Result of error-aware bipack function -pub(crate) type Res = Result; +pub(crate) type Result = std::result::Result; /// There is not enought data to fulfill the request #[derive(Debug, Clone)] @@ -29,25 +29,29 @@ impl Error for BipackError {} /// /// To implement source for other type, implement just [u8()] or mayve also /// [fixed_bytes] for effectiveness. +/// +/// Unlike the [crate::bipack_sink::BipackSink] the source is returning errors. This is because +/// it often appears when reading data do not correspond to the packed one, and this is an often +/// case that requires proper reaction, not just a panic attack :) pub trait BipackSource { - fn get_u8(self: &mut Self) -> Res; + fn get_u8(self: &mut Self) -> Result; - fn get_u16(self: &mut Self) -> Res { + fn get_u16(self: &mut Self) -> Result { Ok(((self.get_u8()? as u16) << 8) + (self.get_u8()? as u16)) } - fn get_u32(self: &mut Self) -> Res { + fn get_u32(self: &mut Self) -> Result { Ok(((self.get_u16()? as u32) << 16) + (self.get_u16()? as u32)) } - fn get_u64(self: &mut Self) -> Res { + fn get_u64(self: &mut Self) -> Result { Ok(((self.get_u32()? as u64) << 32) | (self.get_u32()? as u64)) } /// Unpack variable-length packed unsigned value, used aslo internally to store size /// of arrays, binary data, strings, etc. To pack use /// [crate::bipack_sink::BipackSink::put_unsigned()]. - fn get_unsigned(self: &mut Self) -> Res { - let mut get = || -> Res { Ok(self.get_u8()? as u64) }; + fn get_unsigned(self: &mut Self) -> Result { + let mut get = || -> Result { Ok(self.get_u8()? as u64) }; let first = get()?; let mut ty = first & 3; @@ -68,7 +72,7 @@ pub trait BipackSource { /// read 8-bytes varint-packed unsigned value from the source. We dont' recommend /// using it directly; use [get_unsigned] instead. - fn get_varint_unsigned(self: &mut Self) -> Res { + fn get_varint_unsigned(self: &mut Self) -> Result { let mut result = 0u64; let mut count = 0; loop { @@ -81,17 +85,17 @@ pub trait BipackSource { /// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned] /// as u16 - fn get_packed_u16(self: &mut Self) -> Res { + fn get_packed_u16(self: &mut Self) -> Result { Ok(self.get_unsigned()? as u16) } /// read 4-bytes unsigned value from the source /// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned] /// as u32 - fn get_packed_u32(self: &mut Self) -> Res { Ok(self.get_unsigned()? as u32) } + fn get_packed_u32(self: &mut Self) -> Result { Ok(self.get_unsigned()? as u32) } /// read exact number of bytes from the source as a vec. - fn get_fixed_bytes(self: &mut Self, size: usize) -> Res> { + fn get_fixed_bytes(self: &mut Self, size: usize) -> Result> { let mut result = Vec::with_capacity(size); for i in 0..size { result.push(self.get_u8()?); } Ok(result) @@ -101,7 +105,7 @@ pub trait BipackSource { /// by [BipackSink::put_var_bytes] or [BipackSink::put_string]. The size is encoded /// the same way as does [BipackSink::put_unsigned] and can be manually read by /// [BipackSource::get_unsigned]. - fn var_bytes(self: &mut Self) -> Res> { + fn var_bytes(self: &mut Self) -> Result> { let size = self.get_unsigned()? as usize; self.get_fixed_bytes(size) } @@ -109,7 +113,7 @@ pub trait BipackSource { /// REad a variable length string from a source packed with /// [BipavkSink::put_string]. It is a variable sized array fo utf8 encoded /// characters. - fn str(self: &mut Self) -> Res { + fn str(self: &mut Self) -> Result { String::from_utf8( self.var_bytes()? ).or_else(|e| Err(BipackError::BadEncoding(e))) @@ -130,7 +134,7 @@ impl<'a> SliceSource<'a> { } impl<'x> BipackSource for SliceSource<'x> { - fn get_u8(self: &mut Self) -> Res { + fn get_u8(self: &mut Self) -> Result { if self.position >= self.data.len() { Err(NoDataError) } else { diff --git a/src/lib.rs b/src/lib.rs index ee4e8a9..6ddf52a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,14 +19,13 @@ mod to_dump; #[cfg(test)] mod tests { - use std::error::Error; use base64::Engine; use crate::bipack_sink::{BipackSink}; - use crate::bipack_source::{BipackSource, Res, SliceSource}; + use crate::bipack_source::{BipackSource, Result, SliceSource}; use crate::to_dump::to_dump; #[test] - fn fixed_unpack() -> Result<(),Box> { + fn fixed_unpack() -> Result<()> { let mut src = Vec::new(); base64::engine::general_purpose::STANDARD_NO_PAD .decode_vec("B/oAAAEB0AAAANjLgKAv", &mut src) @@ -42,7 +41,7 @@ mod tests { } #[test] - fn smartint_unpack() -> Res<()> { + fn smartint_unpack() -> Result<()> { let mut src = Vec::new(); base64::engine::general_purpose::STANDARD_NO_PAD .decode_vec("BwLoA0IHBL+AAq7GDQ", &mut src)