docs, preparing for publication

This commit is contained in:
Sergey Chernov 2023-10-09 22:42:53 +01:00
parent 131859ffba
commit e06d553ed7
3 changed files with 28 additions and 19 deletions

View File

@ -26,7 +26,13 @@ into_u64!(u8, u16, u32, usize, u64);
/// Data sink to encode bipack binary format. /// 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 { pub trait BipackSink {
fn put_u8(self: &mut Self, data: u8); fn put_u8(self: &mut Self, data: u8);

View File

@ -4,7 +4,7 @@ use std::string::FromUtf8Error;
use crate::bipack_source::BipackError::NoDataError; use crate::bipack_source::BipackError::NoDataError;
/// Result of error-aware bipack function /// Result of error-aware bipack function
pub(crate) type Res<T> = Result<T, BipackError>; pub(crate) type Result<T> = std::result::Result<T, BipackError>;
/// There is not enought data to fulfill the request /// There is not enought data to fulfill the request
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -29,25 +29,29 @@ impl Error for BipackError {}
/// ///
/// To implement source for other type, implement just [u8()] or mayve also /// To implement source for other type, implement just [u8()] or mayve also
/// [fixed_bytes] for effectiveness. /// [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 { pub trait BipackSource {
fn get_u8(self: &mut Self) -> Res<u8>; fn get_u8(self: &mut Self) -> Result<u8>;
fn get_u16(self: &mut Self) -> Res<u16> { fn get_u16(self: &mut Self) -> Result<u16> {
Ok(((self.get_u8()? as u16) << 8) + (self.get_u8()? as u16)) Ok(((self.get_u8()? as u16) << 8) + (self.get_u8()? as u16))
} }
fn get_u32(self: &mut Self) -> Res<u32> { fn get_u32(self: &mut Self) -> Result<u32> {
Ok(((self.get_u16()? as u32) << 16) + (self.get_u16()? as u32)) Ok(((self.get_u16()? as u32) << 16) + (self.get_u16()? as u32))
} }
fn get_u64(self: &mut Self) -> Res<u64> { fn get_u64(self: &mut Self) -> Result<u64> {
Ok(((self.get_u32()? as u64) << 32) | (self.get_u32()? as u64)) Ok(((self.get_u32()? as u64) << 32) | (self.get_u32()? as u64))
} }
/// Unpack variable-length packed unsigned value, used aslo internally to store size /// Unpack variable-length packed unsigned value, used aslo internally to store size
/// of arrays, binary data, strings, etc. To pack use /// of arrays, binary data, strings, etc. To pack use
/// [crate::bipack_sink::BipackSink::put_unsigned()]. /// [crate::bipack_sink::BipackSink::put_unsigned()].
fn get_unsigned(self: &mut Self) -> Res<u64> { fn get_unsigned(self: &mut Self) -> Result<u64> {
let mut get = || -> Res<u64> { Ok(self.get_u8()? as u64) }; let mut get = || -> Result<u64> { Ok(self.get_u8()? as u64) };
let first = get()?; let first = get()?;
let mut ty = first & 3; 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 /// read 8-bytes varint-packed unsigned value from the source. We dont' recommend
/// using it directly; use [get_unsigned] instead. /// using it directly; use [get_unsigned] instead.
fn get_varint_unsigned(self: &mut Self) -> Res<u64> { fn get_varint_unsigned(self: &mut Self) -> Result<u64> {
let mut result = 0u64; let mut result = 0u64;
let mut count = 0; let mut count = 0;
loop { loop {
@ -81,17 +85,17 @@ pub trait BipackSource {
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned] /// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
/// as u16 /// as u16
fn get_packed_u16(self: &mut Self) -> Res<u16> { fn get_packed_u16(self: &mut Self) -> Result<u16> {
Ok(self.get_unsigned()? as u16) Ok(self.get_unsigned()? as u16)
} }
/// read 4-bytes unsigned value from the source /// read 4-bytes unsigned value from the source
/// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned] /// read 2-bytes unsigned value from the source as smartint-encoded, same as [get_unsigned]
/// as u32 /// as u32
fn get_packed_u32(self: &mut Self) -> Res<u32> { Ok(self.get_unsigned()? as u32) } fn get_packed_u32(self: &mut Self) -> Result<u32> { Ok(self.get_unsigned()? as u32) }
/// read exact number of bytes from the source as a vec. /// read exact number of bytes from the source as a vec.
fn get_fixed_bytes(self: &mut Self, size: usize) -> Res<Vec<u8>> { fn get_fixed_bytes(self: &mut Self, size: usize) -> Result<Vec<u8>> {
let mut result = Vec::with_capacity(size); let mut result = Vec::with_capacity(size);
for i in 0..size { result.push(self.get_u8()?); } for i in 0..size { result.push(self.get_u8()?); }
Ok(result) Ok(result)
@ -101,7 +105,7 @@ pub trait BipackSource {
/// by [BipackSink::put_var_bytes] or [BipackSink::put_string]. The size is encoded /// 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 /// the same way as does [BipackSink::put_unsigned] and can be manually read by
/// [BipackSource::get_unsigned]. /// [BipackSource::get_unsigned].
fn var_bytes(self: &mut Self) -> Res<Vec<u8>> { fn var_bytes(self: &mut Self) -> Result<Vec<u8>> {
let size = self.get_unsigned()? as usize; let size = self.get_unsigned()? as usize;
self.get_fixed_bytes(size) self.get_fixed_bytes(size)
} }
@ -109,7 +113,7 @@ pub trait BipackSource {
/// REad a variable length string from a source packed with /// REad a variable length string from a source packed with
/// [BipavkSink::put_string]. It is a variable sized array fo utf8 encoded /// [BipavkSink::put_string]. It is a variable sized array fo utf8 encoded
/// characters. /// characters.
fn str(self: &mut Self) -> Res<String> { fn str(self: &mut Self) -> Result<String> {
String::from_utf8( String::from_utf8(
self.var_bytes()? self.var_bytes()?
).or_else(|e| Err(BipackError::BadEncoding(e))) ).or_else(|e| Err(BipackError::BadEncoding(e)))
@ -130,7 +134,7 @@ impl<'a> SliceSource<'a> {
} }
impl<'x> BipackSource for SliceSource<'x> { impl<'x> BipackSource for SliceSource<'x> {
fn get_u8(self: &mut Self) -> Res<u8> { fn get_u8(self: &mut Self) -> Result<u8> {
if self.position >= self.data.len() { if self.position >= self.data.len() {
Err(NoDataError) Err(NoDataError)
} else { } else {

View File

@ -19,14 +19,13 @@ mod to_dump;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::error::Error;
use base64::Engine; use base64::Engine;
use crate::bipack_sink::{BipackSink}; 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; use crate::to_dump::to_dump;
#[test] #[test]
fn fixed_unpack() -> Result<(),Box<dyn Error>> { fn fixed_unpack() -> Result<()> {
let mut src = Vec::new(); let mut src = Vec::new();
base64::engine::general_purpose::STANDARD_NO_PAD base64::engine::general_purpose::STANDARD_NO_PAD
.decode_vec("B/oAAAEB0AAAANjLgKAv", &mut src) .decode_vec("B/oAAAEB0AAAANjLgKAv", &mut src)
@ -42,7 +41,7 @@ mod tests {
} }
#[test] #[test]
fn smartint_unpack() -> Res<()> { fn smartint_unpack() -> Result<()> {
let mut src = Vec::new(); let mut src = Vec::new();
base64::engine::general_purpose::STANDARD_NO_PAD base64::engine::general_purpose::STANDARD_NO_PAD
.decode_vec("BwLoA0IHBL+AAq7GDQ", &mut src) .decode_vec("BwLoA0IHBL+AAq7GDQ", &mut src)