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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user