1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! This library is a Rust implementation of the https://github.com/multiformats/multicodec project. extern crate integer_encoding; use std::io::Write; use integer_encoding::VarInt; mod codec_map; /// Returns the data prefixed with the codec's code in a u8 buffer. /// /// # Arguments /// /// * `codec_code` - The codec code, eg. 'base1' /// * `data` - the data to be prefixed /// /// # Example /// /// ``` /// extern crate rust_multicodec; /// extern crate hex_slice; /// /// use hex_slice::AsHex; /// use std::process; /// /// fn main(){ /// let data="Live long and prosper"; /// /// println!("{:X}",rust_multicodec::add_prefix("base1",data.as_bytes()).unwrap().as_hex()); /// // it will print [1 4C 69 76 65 20 6C 6F 6E 67 20 61 6E 64 20 70 72 6F 73 70 65 72] /// } /// ``` /// pub fn add_prefix(codec_code: &str, data: &[u8]) -> Result<Vec<u8>, &'static str> { match codec_map::get_decimal_by_code(codec_code) { // getting hex code of the codec Some(decimal) => { // encoding codec's (as decimal) into a varint let mut target:Vec<u8>=decimal.encode_var_vec(); match target.write(data) { Err(_) => return Err("Could not write data into the result buffer"), _=> () } Ok(target) } None => Err("No implementation for the given codec") } } /// Returns the codec's code the data was prefixed with. /// /// # Arguments /// /// * `data` - the data with prefix /// /// # Example /// /// ``` /// extern crate rust_multicodec; /// extern crate hex_slice; /// /// use hex_slice::AsHex; /// use std::process; /// /// fn main(){ /// let data="Live long and prosper"; /// /// let prefixed=rust_multicodec::add_prefix("base1",data.as_bytes()).unwrap(); /// println!("{}",rust_multicodec::get_codec(prefixed.as_slice()).unwrap().unwrap()); /// // it will print "base1" /// } /// ``` /// pub fn get_codec(data: &[u8]) -> Result<Option<&'static str>, &'static str> { let decoded:(u64,usize)=u64::decode_var_vec(&Vec::from(data)); Ok(codec_map::get_code_by_decimal(decoded.0)) } /// Removes the codec prefix and returns the raw data. /// /// # Arguments /// /// * `data` - the data with prefix /// /// # Example /// /// ``` /// extern crate rust_multicodec; /// extern crate hex_slice; /// /// use hex_slice::AsHex; /// use std::process; /// /// fn main(){ /// let data="Live long and prosper"; /// /// let prefixed=rust_multicodec::add_prefix("base1",data.as_bytes()).unwrap(); /// let raw_data=rust_multicodec::remove_prefix(prefixed.as_slice()).unwrap(); /// println!("Original data was {:?}", String::from_utf8(raw_data).unwrap()) /// // it will print return "Original data was Live long and prosper" /// } /// ``` /// pub fn remove_prefix(data:&[u8]) -> Result<Vec<u8>, &'static str>{ let decoded:(u64,usize)=u64::decode_var_vec(&Vec::from(data)); Ok(data[decoded.1..].to_vec()) } #[cfg(test)] mod tests { use super::*; const DATA:&str="Live long and prosper"; #[test] fn works(){ let result=add_prefix("utp",DATA.as_bytes()); assert_eq!(result.is_ok(),true); let prefixed=result.unwrap(); assert_eq!(get_codec(prefixed.as_slice()).unwrap().unwrap(),"utp"); assert_eq!(remove_prefix(prefixed.as_slice()).unwrap(),DATA.as_bytes()); } #[test] #[should_panic] fn fails_with_invalid_codec(){ add_prefix("invalid_codec",DATA.as_bytes()).unwrap(); } }