bencode encoding
This commit is contained in:
73
src/bencode/encode.rs
Normal file
73
src/bencode/encode.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use bencode::Object;
|
||||
|
||||
pub fn encode<B>(obj: B) -> Vec<u8> where B: Borrow<Object> {
|
||||
let mut buff = Vec::new();
|
||||
encode_object(&mut buff, obj.borrow());
|
||||
buff
|
||||
}
|
||||
|
||||
fn encode_object(buff: &mut Vec<u8>, obj: &Object) {
|
||||
match *obj {
|
||||
Object::Int(num) => encode_int(buff, num),
|
||||
Object::Bytes(ref bytes) => encode_bytes(buff, bytes),
|
||||
Object::List(ref list) => encode_list(buff, list),
|
||||
Object::Dict(ref dict) => encode_dict(buff, dict),
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_int(buff: &mut Vec<u8>, num: i64) {
|
||||
buff.extend_from_slice(format!("i{}e", num).as_bytes());
|
||||
}
|
||||
|
||||
fn encode_bytes(buff: &mut Vec<u8>, bytes: &[u8]) {
|
||||
buff.extend_from_slice(format!("{}:", bytes.len()).as_bytes());
|
||||
buff.extend_from_slice(bytes);
|
||||
}
|
||||
|
||||
fn encode_list(buff: &mut Vec<u8>, list: &[Object]) {
|
||||
buff.push(b'l');
|
||||
for obj in list {
|
||||
encode_object(buff, obj);
|
||||
}
|
||||
buff.push(b'e');
|
||||
}
|
||||
|
||||
fn encode_dict(buff: &mut Vec<u8>, dict: &BTreeMap<Vec<u8>, Object>) {
|
||||
buff.push(b'd');
|
||||
for (key, val) in dict {
|
||||
encode_bytes(buff, key);
|
||||
encode_object(buff, val);
|
||||
}
|
||||
buff.push(b'e');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_pos() {
|
||||
assert_eq!(encode(Object::Int(1337)), b"i1337e");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int_neg() {
|
||||
assert_eq!(encode(Object::Int(-1337)), b"i-1337e");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes() {
|
||||
assert_eq!(encode(Object::Bytes(b"hello".to_vec())), b"5:hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list() {
|
||||
let list = vec![Object::Int(1), Object::Int(2), Object::Int(3)];
|
||||
assert_eq!(encode(Object::List(list)), b"li1ei2ei3ee");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dict() {
|
||||
let mut dict = BTreeMap::new();
|
||||
dict.insert(b"hello".to_vec(), Object::Int(1337));
|
||||
assert_eq!(encode(Object::Dict(dict)), b"d5:helloi1337ee")
|
||||
}
|
||||
Reference in New Issue
Block a user