0.2.0: improving nameing, started serialization support and convenience macros.
This commit is contained in:
parent
c1aaede6f7
commit
33a27d0124
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "bipack_ru"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
description = "binary size-effective format used in Divan smart contracts, wasm bindings, network protocols, etc."
|
||||
|
@ -1,5 +1,8 @@
|
||||
# bipack_ru
|
||||
|
||||
> This is yet an alpha. We are still experimenting with the interface. 0.1.* could
|
||||
> be backward incompatible!
|
||||
|
||||
Bipack format implementation, minimalistic by purpose.
|
||||
|
||||
At the moment it does not include `serde` module as it is yet unclear how much
|
||||
@ -9,4 +12,4 @@ The autodoc documentation is good enough already, so we do not repeat it here no
|
||||
|
||||
# License
|
||||
|
||||
For compyance with other modules this work is provided under APACHE 2.0 license a copy of which is included in the file `LICENSE`.
|
||||
For compliance with other modules this work is provided under APACHE 2.0 license a copy of which is included in the file `LICENSE`.
|
79
src/bipack.rs
Normal file
79
src/bipack.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use crate::bipack_sink::{BipackSink, IntoU64};
|
||||
use crate::bipack_source::{BipackSource, Result};
|
||||
|
||||
/// The trait to unpack to be used in serializer to come. Please don't use it, it is
|
||||
/// experimental.
|
||||
pub trait BiPackable {
|
||||
fn bi_pack(self: &Self, sink: &mut impl BipackSink);
|
||||
}
|
||||
|
||||
/// The trait need by [bipack()] macro and in the serializer to come, packs some
|
||||
/// type into a generic sink.
|
||||
pub trait BiUnpackable where Self: Sized {
|
||||
|
||||
fn bi_unpack(source: &mut dyn BipackSource) -> Result<Self>;
|
||||
}
|
||||
|
||||
/// Pack all arguments according to their type, using variable-length
|
||||
/// encoding for integers and default encoding for binaries and string,
|
||||
/// and return `Vec<u8>` with packed result.
|
||||
///
|
||||
/// It you need more fine-grained packing, use [BipackSink] directly.
|
||||
#[macro_export]
|
||||
macro_rules! bipack {
|
||||
( $( $e: expr),* ) => {{
|
||||
let mut result = Vec::new();
|
||||
$(
|
||||
$e.bi_pack(&mut result);
|
||||
)*
|
||||
result
|
||||
}};
|
||||
}
|
||||
|
||||
impl<T: IntoU64 + Copy> BiPackable for T {
|
||||
fn bi_pack(self: &Self, sink: &mut impl BipackSink) {
|
||||
sink.put_unsigned(self.into_u64())
|
||||
}
|
||||
}
|
||||
|
||||
impl BiPackable for &str {
|
||||
fn bi_pack(self: &Self, sink: &mut impl BipackSink) {
|
||||
sink.put_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! declare_unpack_u {
|
||||
($($type:ident),*) => {
|
||||
$(impl BiUnpackable for $type {
|
||||
fn bi_unpack(source: &mut dyn BipackSource) -> Result<$type> {
|
||||
Ok(source.get_unsigned()? as $type)
|
||||
}
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
declare_unpack_u!(u16, u32, u64);
|
||||
|
||||
// impl<String> BiUnpackable<String> for String {
|
||||
// fn bi_unpack(source: &mut impl BipackSource) -> Result<Self> {
|
||||
// source.get_str()
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl dyn BiUnpackable<u32> {
|
||||
//
|
||||
// }
|
||||
|
||||
impl BiUnpackable for u8 {
|
||||
fn bi_unpack(source: &mut dyn BipackSource) -> Result<u8> {
|
||||
source.get_u8()
|
||||
}
|
||||
}
|
||||
|
||||
impl BiUnpackable for String {
|
||||
fn bi_unpack(source: &mut dyn BipackSource) -> Result<String> {
|
||||
source.get_str()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ pub trait BipackSource {
|
||||
/// [crate::bipack_sink::BipackSink::put_str]. The size is encoded the same way as does
|
||||
/// [crate::bipack_sink::BipackSink::put_unsigned] and can be manually read by
|
||||
/// [BipackSource::get_unsigned].
|
||||
fn var_bytes(self: &mut Self) -> Result<Vec<u8>> {
|
||||
fn get_var_bytes(self: &mut Self) -> Result<Vec<u8>> {
|
||||
let size = self.get_unsigned()? as usize;
|
||||
self.get_fixed_bytes(size)
|
||||
}
|
||||
@ -128,9 +128,9 @@ pub trait BipackSource {
|
||||
/// REad a variable length string from a source packed with
|
||||
/// [crate::bipack_sink::BipackSink::put_str]. It is a variable sized array fo utf8 encoded
|
||||
/// characters.
|
||||
fn str(self: &mut Self) -> Result<String> {
|
||||
fn get_str(self: &mut Self) -> Result<String> {
|
||||
String::from_utf8(
|
||||
self.var_bytes()?
|
||||
self.get_var_bytes()?
|
||||
).or_else(|e| Err(BipackError::BadEncoding(e)))
|
||||
}
|
||||
}
|
||||
|
22
src/lib.rs
22
src/lib.rs
@ -117,11 +117,15 @@
|
||||
pub mod bipack_source;
|
||||
pub mod bipack_sink;
|
||||
pub mod tools;
|
||||
mod bipack;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base64::Engine;
|
||||
use crate::bipack_sink::{BipackSink};
|
||||
|
||||
use crate::bipack;
|
||||
use crate::bipack::{BiPackable, BiUnpackable};
|
||||
use crate::bipack_sink::BipackSink;
|
||||
use crate::bipack_source::{BipackSource, Result, SliceSource};
|
||||
use crate::tools::to_dump;
|
||||
|
||||
@ -182,7 +186,7 @@ mod tests {
|
||||
data.put_str("Hello, rupack!");
|
||||
println!("size ${}\n{}",data.len(), to_dump(&data));
|
||||
let mut src = SliceSource::from(&data);
|
||||
assert_eq!("Hello, rupack!", src.str().unwrap());
|
||||
assert_eq!("Hello, rupack!", src.get_str().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -201,4 +205,18 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_packer() -> Result<()>{
|
||||
let a = 177u32;
|
||||
let b = "hello!";
|
||||
let sink = bipack!(a, b);
|
||||
println!("{}", to_dump(&sink));
|
||||
let mut source = SliceSource::from(&sink);
|
||||
let a1 = u32::bi_unpack(&mut source)?;
|
||||
let s1 = String::bi_unpack(&mut source)?;
|
||||
assert_eq!(177u32, a1);
|
||||
assert_eq!("hello!", s1);
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user