1pub use super::*;
2
3#[cfg(test)]
4mod tests {
5
6 use Bencoding;
7 use libencode::encode;
8 use libdecode::decode;
9 use std::collections::HashMap;
10
11 #[test]
12 fn test_run() {
13 assert!(true);
14 }
15
16 struct TestCase {
17 pub input: Vec<u8>,
18 pub expected: Bencoding,
19 }
20
21 #[test]
22 fn test_encode_number() {
23 let test_cases: Vec<TestCase> = vec![
24 TestCase{
25 input: vec![105, 49, 50, 51, 101],
26 expected: Bencoding::Integer(123) },
27 TestCase{
28 input: vec![105, 57, 56, 55, 101],
29 expected: Bencoding::Integer(987) },
30 ];
31
32 for t in test_cases {
35 println!("test number encode...");
36 let decode_input = t.input.clone();
37 let test_input = t.input.clone();
38 let benc = decode(decode_input);
39 let num = encode(benc);
40 println!("expect: {:?} ; got: {:?}", test_input, num);
41 assert!(test_input == num);
42 }
43 }
44
45 #[test]
46 fn test_encode_bytestring() {
47 let test_cases: Vec<TestCase> = vec![
48 TestCase{
49 input: vec![51, 58, 117, 118, 119],
50 expected: Bencoding::ByteString("uvw".to_string().into_bytes())
51 },
52 TestCase{
53 input: vec![51, 58, 120, 121, 122],
54 expected: Bencoding::ByteString("xyz".to_string().into_bytes())
55 },
56 ];
57
58 for t in test_cases {
61 let decode_input = t.input.clone();
62 let test_input = t.input.clone();
63 let benc = decode(decode_input);
64 let str = encode(benc);
65 assert!(test_input == str);
66 }
67 }
68
69 #[test]
70 fn test_encode_list() {
71 let test_cases: Vec<TestCase> = vec![
72 TestCase{
73 input: "l5:ItemA5:ItemBe".to_string().into_bytes(),
74 expected: Bencoding::List( vec![
75 Bencoding::ByteString("ItemA".to_string().into_bytes()),
76 Bencoding::ByteString("ItemB".to_string().into_bytes())
77 ])
78 },
79 ];
80
81 for t in test_cases {
84 let decode_input = t.input.clone();
85 let test_input = t.input.clone();
86 let benc = decode(decode_input);
87 let str = encode(benc);
88 assert!(test_input == str);
89 }
90 }
91
92 #[test]
93 fn test_encode_dictionary() {
94
95 let mut test_result: HashMap<Vec<u8>, Bencoding> = HashMap::new();
96 test_result.insert(
97 "announce".to_string().into_bytes(),
98 Bencoding::ByteString("http://192.168.1.74:6969/announce".to_string().into_bytes()));
99 test_result.insert(
100 "comment".to_string().into_bytes(),
101 Bencoding::ByteString("This is a comment".to_string().into_bytes()));
102 let test_cases: Vec<TestCase> = vec![
103 TestCase{
104 input: "d8:announce33:http://192.168.1.74:6969/announce7:comment17:This is a commente".to_string().into_bytes(),
105 expected: Bencoding::Dictionary(test_result)
106 },
107 ];
108
109 for t in test_cases {
112 let decode_input = t.input.clone();
113 let test_input = t.input.clone();
114 let benc = decode(decode_input);
115 let s = encode(benc);
116 assert!(test_input == s);
117 }
118
119 }
120}
121
122pub fn encode(benc: Bencoding) -> Vec<u8> {
124 let mut mem_stream = vec![];
125 encode_next(&mut mem_stream, benc);
126 mem_stream
127}
128
129fn encode_next(mem_stream: &mut Vec<u8>, obj: Bencoding) {
130 match obj {
131 Bencoding::Integer(ref v) => {
132 encode_number(mem_stream, Bencoding::Integer(*v))
133 }
134 Bencoding::ByteString(ref v) => {
135 let v_2 = v.clone();
136 encode_bytestring(mem_stream, Bencoding::ByteString(v_2))
137 }
138 Bencoding::List(ref v) => {
139 let v_2 = v.clone();
140 encode_list(mem_stream, Bencoding::List(v_2))
141 }
142 Bencoding::Dictionary(ref v) => {
143 let v_2 = v.clone();
144 encode_dictionary(mem_stream, Bencoding::Dictionary(v_2))
145 }
146 _ => {
147 println!("panic on obj: {:?}, unexpected type", obj);
148 }
149 };
150}
151
152fn encode_number(mem_stream: &mut Vec<u8>, num: Bencoding) {
153 mem_stream.push(NUMBER_START);
154 let mut val = match num {
155 Bencoding::Integer(ref v) => v.to_string().into_bytes(),
156 _ => panic!("unexpected type"),
157 };
158 mem_stream.append(&mut val);
159 mem_stream.push(NUMBER_END);
160}
161
162fn encode_bytestring(mem_stream: &mut Vec<u8>, benc_str: Bencoding) {
163 let mut str = match benc_str {
164 Bencoding::ByteString(v) => v,
165 _ => panic!("unexpected type"),
166 };
167 mem_stream.append(& mut str.len().to_string().into_bytes());
168 mem_stream.push(58);
169 mem_stream.append(&mut str);
170}
171
172fn encode_list(mem_stream: &mut Vec<u8>, benc_list: Bencoding) {
175 mem_stream.push(LIST_START);
176 let val = match benc_list {
178 Bencoding::List(ref v) => v,
179 _ => panic!("unexpected type"),
180 };
181 for i in val {
182 let ii = i.clone();
183 encode_next(mem_stream, ii);
184 }
185 mem_stream.push(LIST_END);
186}
187
188fn encode_dictionary(mem_stream: &mut Vec<u8>, benc_dict: Bencoding) {
189 mem_stream.push(DICTIONARY_START);
190 let val = match benc_dict {
192 Bencoding::Dictionary(ref v) => v,
193 _ => panic!("unexpected type"),
194 };
195
196 let mut keys: Vec<Vec<u8>> = vec![];
197
198 for key in val.keys() {
199 let key_2 = key.clone();
200 keys.push(key_2);
201 }
202 keys.sort();
203 for k in keys {
204 let kk = k.clone();
205
206 let vv = match val.get(&kk) {
207 Some(o) => o.clone(),
208 _ => panic!("no such key in dictionary"),
209 };
210
211 encode_next(mem_stream, Bencoding::ByteString(kk));
212 encode_next(mem_stream, vv);
213 }
214 mem_stream.push(DICTIONARY_END);
215}