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]
|
[package]
|
||||||
name = "bipack_ru"
|
name = "bipack_ru"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
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."
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
# bipack_ru
|
# 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.
|
Bipack format implementation, minimalistic by purpose.
|
||||||
|
|
||||||
At the moment it does not include `serde` module as it is yet unclear how much
|
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
|
# 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_str]. The size is encoded the same way as does
|
||||||
/// [crate::bipack_sink::BipackSink::put_unsigned] and can be manually read by
|
/// [crate::bipack_sink::BipackSink::put_unsigned] and can be manually read by
|
||||||
/// [BipackSource::get_unsigned].
|
/// [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;
|
let size = self.get_unsigned()? as usize;
|
||||||
self.get_fixed_bytes(size)
|
self.get_fixed_bytes(size)
|
||||||
}
|
}
|
||||||
@ -128,9 +128,9 @@ pub trait BipackSource {
|
|||||||
/// REad a variable length string from a source packed with
|
/// 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
|
/// [crate::bipack_sink::BipackSink::put_str]. It is a variable sized array fo utf8 encoded
|
||||||
/// characters.
|
/// characters.
|
||||||
fn str(self: &mut Self) -> Result<String> {
|
fn get_str(self: &mut Self) -> Result<String> {
|
||||||
String::from_utf8(
|
String::from_utf8(
|
||||||
self.var_bytes()?
|
self.get_var_bytes()?
|
||||||
).or_else(|e| Err(BipackError::BadEncoding(e)))
|
).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_source;
|
||||||
pub mod bipack_sink;
|
pub mod bipack_sink;
|
||||||
pub mod tools;
|
pub mod tools;
|
||||||
|
mod bipack;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use base64::Engine;
|
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::bipack_source::{BipackSource, Result, SliceSource};
|
||||||
use crate::tools::to_dump;
|
use crate::tools::to_dump;
|
||||||
|
|
||||||
@ -182,7 +186,7 @@ mod tests {
|
|||||||
data.put_str("Hello, rupack!");
|
data.put_str("Hello, rupack!");
|
||||||
println!("size ${}\n{}",data.len(), to_dump(&data));
|
println!("size ${}\n{}",data.len(), to_dump(&data));
|
||||||
let mut src = SliceSource::from(&data);
|
let mut src = SliceSource::from(&data);
|
||||||
assert_eq!("Hello, rupack!", src.str().unwrap());
|
assert_eq!("Hello, rupack!", src.get_str().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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