1pub use cookie_factory::{BackToTheBuffer, GenError, GenResult, SerializeFn};
3
4use crate::{flags::*, types::*, value::*};
5use cookie_factory::{
6 bytes::{be_f32, be_f64, be_i8, be_i16, be_i32, be_i64, be_u8, be_u16, be_u32, be_u64},
7 combinator::{back_to_the_buffer, slice},
8 multi::many_ref,
9 sequence::pair,
10};
11use std::io::Write;
12
13pub fn gen_with_len<W: Write + BackToTheBuffer, F: SerializeFn<W>>(f: F) -> impl SerializeFn<W> {
15 back_to_the_buffer(
16 4,
17 move |x| {
18 let start = x.position;
19 let x = f(x)?;
20 let len = x.position - start;
21 Ok((x, len))
22 },
23 move |x, len| gen_long_uint(len as LongUInt)(x),
24 )
25}
26
27pub fn gen_raw_value<'a, W: Write + BackToTheBuffer + 'a>(
29 v: &'a AMQPValue,
30) -> impl SerializeFn<W> + 'a {
31 move |x| match *v {
32 AMQPValue::Boolean(b) => gen_boolean(b)(x),
33 AMQPValue::ShortShortInt(i) => gen_short_short_int(i)(x),
34 AMQPValue::ShortShortUInt(u) => gen_short_short_uint(u)(x),
35 AMQPValue::ShortInt(i) => gen_short_int(i)(x),
36 AMQPValue::ShortUInt(u) => gen_short_uint(u)(x),
37 AMQPValue::LongInt(i) => gen_long_int(i)(x),
38 AMQPValue::LongUInt(u) => gen_long_uint(u)(x),
39 AMQPValue::LongLongInt(i) => gen_long_long_int(i)(x),
40 AMQPValue::Float(f) => gen_float(f)(x),
41 AMQPValue::Double(d) => gen_double(d)(x),
42 AMQPValue::DecimalValue(d) => gen_decimal_value(d)(x),
43 AMQPValue::ShortString(ref s) => gen_short_string(s.as_str())(x),
44 AMQPValue::LongString(ref s) => gen_long_string(s.as_bytes())(x),
45 AMQPValue::FieldArray(ref a) => gen_field_array(a)(x),
46 AMQPValue::Timestamp(t) => gen_timestamp(t)(x),
47 AMQPValue::FieldTable(ref t) => gen_field_table(t)(x),
48 AMQPValue::ByteArray(ref a) => gen_byte_array(a)(x),
49 AMQPValue::Void => Ok(x),
50 }
51}
52
53pub fn gen_value<'a, W: Write + BackToTheBuffer + 'a>(
55 v: &'a AMQPValue,
56) -> impl SerializeFn<W> + 'a {
57 pair(gen_type(v.get_type()), gen_raw_value(v))
58}
59
60pub fn gen_type<W: Write>(t: AMQPType) -> impl SerializeFn<W> {
62 gen_short_short_uint(t.get_id() as ShortShortUInt)
63}
64
65pub fn gen_id<W: Write>(id: ShortUInt) -> impl SerializeFn<W> {
67 gen_short_uint(id)
68}
69
70pub fn gen_boolean<W: Write>(b: Boolean) -> impl SerializeFn<W> {
72 gen_short_short_uint(if b { 1 } else { 0 })
73}
74
75pub fn gen_short_short_int<W: Write>(i: ShortShortInt) -> impl SerializeFn<W> {
77 be_i8(i)
78}
79
80pub fn gen_short_short_uint<W: Write>(u: ShortShortUInt) -> impl SerializeFn<W> {
82 be_u8(u)
83}
84
85pub fn gen_short_int<W: Write>(i: ShortInt) -> impl SerializeFn<W> {
87 be_i16(i)
88}
89
90pub fn gen_short_uint<W: Write>(u: ShortUInt) -> impl SerializeFn<W> {
92 be_u16(u)
93}
94
95pub fn gen_long_int<W: Write>(i: LongInt) -> impl SerializeFn<W> {
97 be_i32(i)
98}
99
100pub fn gen_long_uint<W: Write>(u: LongUInt) -> impl SerializeFn<W> {
102 be_u32(u)
103}
104
105pub fn gen_long_long_int<W: Write>(i: LongLongInt) -> impl SerializeFn<W> {
107 be_i64(i)
108}
109
110pub fn gen_long_long_uint<W: Write>(u: LongLongUInt) -> impl SerializeFn<W> {
112 be_u64(u)
113}
114
115pub fn gen_float<W: Write>(f: Float) -> impl SerializeFn<W> {
117 be_f32(f)
118}
119
120pub fn gen_double<W: Write>(d: Double) -> impl SerializeFn<W> {
122 be_f64(d)
123}
124
125pub fn gen_decimal_value<W: Write>(d: DecimalValue) -> impl SerializeFn<W> {
127 pair(gen_short_short_uint(d.scale), gen_long_uint(d.value))
128}
129
130pub fn gen_short_string<'a, W: Write + 'a>(s: &'a str) -> impl SerializeFn<W> + 'a {
132 pair(
133 gen_short_short_uint(s.len() as ShortShortUInt),
134 slice(s.as_bytes()),
135 )
136}
137
138pub fn gen_long_string<'a, W: Write + 'a>(s: &'a [u8]) -> impl SerializeFn<W> + 'a {
140 pair(gen_long_uint(s.len() as LongUInt), slice(s))
141}
142
143pub fn gen_field_array<'a, W: Write + BackToTheBuffer + 'a>(
145 a: &'a FieldArray,
146) -> impl SerializeFn<W> + 'a {
147 gen_with_len(many_ref(a.as_slice(), move |field| gen_value(field)))
148}
149
150pub fn gen_timestamp<W: Write>(t: Timestamp) -> impl SerializeFn<W> {
152 gen_long_long_uint(t)
153}
154
155pub fn gen_field_table<'a, W: Write + BackToTheBuffer + 'a>(
157 t: &'a FieldTable,
158) -> impl SerializeFn<W> + 'a {
159 gen_with_len(many_ref(t, gen_field_entry))
160}
161
162fn gen_field_entry<'a, W: Write + BackToTheBuffer + 'a>(
163 e: (&'a ShortString, &'a AMQPValue),
164) -> impl SerializeFn<W> + 'a {
165 pair(gen_short_string(e.0.as_str()), gen_value(e.1))
166}
167
168pub fn gen_byte_array<'a, W: Write + 'a>(a: &'a ByteArray) -> impl SerializeFn<W> + 'a {
170 pair(gen_long_uint(a.len() as LongUInt), slice(a.as_slice()))
171}
172
173pub fn gen_flags<'a, W: Write + 'a>(f: &'a AMQPFlags) -> impl SerializeFn<W> + 'a {
175 move |x| {
176 f.get_bytes()
177 .iter()
178 .try_fold(x, |acc, b| gen_short_short_uint(*b)(acc))
179 }
180}
181
182#[cfg(test)]
183mod test {
184 use super::*;
185
186 use cookie_factory::r#gen as cf_gen;
187
188 macro_rules! test_gen (
189 ($buf: expr, $gen: ident, $val: expr) => ({
190 let buf = $buf;
191 let len = cf_gen($gen($val), &mut buf[..]).map(|t| t.1);
192 match len {
193 Err(e) => Err(format!("{:?}", e)),
194 Ok(len) => Ok((buf.to_vec(), len)),
195 }
196 });
197 );
198
199 #[test]
200 fn test_gen_raw_value() {
201 assert_eq!(
202 test_gen!(
203 &mut [0, 0, 0, 0][..],
204 gen_raw_value,
205 &AMQPValue::LongInt(42)
206 ),
207 Ok((vec![0, 0, 0, 42], 4))
208 );
209 assert_eq!(
210 test_gen!(&mut [0][..], gen_raw_value, &AMQPValue::Boolean(true)),
211 Ok((vec![1], 1))
212 );
213 }
214
215 #[test]
216 fn test_gen_value() {
217 assert_eq!(
218 test_gen!(&mut [0, 0, 0, 0, 0][..], gen_value, &AMQPValue::LongInt(42)),
219 Ok((vec![73, 0, 0, 0, 42], 5))
220 );
221 assert_eq!(
222 test_gen!(&mut [0, 0][..], gen_value, &AMQPValue::Boolean(true)),
223 Ok((vec![116, 1], 2))
224 );
225 }
226
227 #[test]
228 fn test_gen_type() {
229 assert_eq!(
230 test_gen!(&mut [0][..], gen_type, AMQPType::ShortShortInt),
231 Ok((vec![98], 1))
232 );
233 assert_eq!(
234 test_gen!(&mut [0][..], gen_type, AMQPType::ShortInt),
235 Ok((vec![115], 1))
236 );
237 }
238
239 #[test]
240 fn test_gen_id() {
241 assert_eq!(test_gen!(&mut [0, 0][..], gen_id, 0), Ok((vec![0, 0], 2)));
242 assert_eq!(
243 test_gen!(&mut [0, 0][..], gen_id, 65535),
244 Ok((vec![255, 255], 2))
245 );
246 }
247
248 #[test]
249 fn test_gen_boolean() {
250 assert_eq!(
251 test_gen!(&mut [0][..], gen_boolean, false),
252 Ok((vec![0], 1))
253 );
254 assert_eq!(test_gen!(&mut [0][..], gen_boolean, true), Ok((vec![1], 1)));
255 }
256
257 #[test]
258 fn test_gen_short_short_int() {
259 assert_eq!(
260 test_gen!(&mut [0][..], gen_short_short_int, 0),
261 Ok((vec![0], 1))
262 );
263 assert_eq!(
264 test_gen!(&mut [0][..], gen_short_short_int, -1),
265 Ok((vec![255], 1))
266 );
267 }
268
269 #[test]
270 fn test_gen_short_short_uint() {
271 assert_eq!(
272 test_gen!(&mut [0][..], gen_short_short_uint, 0),
273 Ok((vec![0], 1))
274 );
275 assert_eq!(
276 test_gen!(&mut [0][..], gen_short_short_uint, 255),
277 Ok((vec![255], 1))
278 );
279 }
280
281 #[test]
282 fn test_gen_short_int() {
283 assert_eq!(
284 test_gen!(&mut [0, 0][..], gen_short_int, 0),
285 Ok((vec![0, 0], 2))
286 );
287 assert_eq!(
288 test_gen!(&mut [0, 0][..], gen_short_int, -1),
289 Ok((vec![255, 255], 2))
290 );
291 }
292
293 #[test]
294 fn test_gen_short_uint() {
295 assert_eq!(
296 test_gen!(&mut [0, 0][..], gen_short_uint, 0),
297 Ok((vec![0, 0], 2))
298 );
299 assert_eq!(
300 test_gen!(&mut [0, 0][..], gen_short_uint, 65535),
301 Ok((vec![255, 255], 2))
302 );
303 }
304
305 #[test]
306 fn test_gen_long_int() {
307 assert_eq!(
308 test_gen!(&mut [0, 0, 0, 0][..], gen_long_int, 0),
309 Ok((vec![0, 0, 0, 0], 4))
310 );
311 assert_eq!(
312 test_gen!(&mut [0, 0, 0, 0][..], gen_long_int, -1),
313 Ok((vec![255, 255, 255, 255], 4))
314 );
315 }
316
317 #[test]
318 fn test_gen_long_uint() {
319 assert_eq!(
320 test_gen!(&mut [0, 0, 0, 0][..], gen_long_uint, 0),
321 Ok((vec![0, 0, 0, 0], 4))
322 );
323 assert_eq!(
324 test_gen!(&mut [0, 0, 0, 0][..], gen_long_uint, 4294967295),
325 Ok((vec![255, 255, 255, 255], 4))
326 );
327 }
328
329 #[test]
330 fn test_gen_long_long_int() {
331 assert_eq!(
332 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_long_long_int, 0),
333 Ok((vec![0, 0, 0, 0, 0, 0, 0, 0], 8))
334 );
335 assert_eq!(
336 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_long_long_int, -1),
337 Ok((vec![255, 255, 255, 255, 255, 255, 255, 255], 8))
338 );
339 }
340
341 #[test]
342 fn test_gen_long_long_uint() {
343 assert_eq!(
344 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_long_long_uint, 0),
345 Ok((vec![0, 0, 0, 0, 0, 0, 0, 0], 8))
346 );
347 assert_eq!(
348 test_gen!(
349 &mut [0, 0, 0, 0, 0, 0, 0, 0][..],
350 gen_long_long_uint,
351 18446744073709551615
352 ),
353 Ok((vec![255, 255, 255, 255, 255, 255, 255, 255], 8))
354 );
355 }
356
357 #[test]
358 fn test_gen_float() {
359 assert_eq!(
360 test_gen!(&mut [0, 0, 0, 0][..], gen_float, 0.),
361 Ok((vec![0, 0, 0, 0], 4))
362 );
363 assert_eq!(
364 test_gen!(&mut [0, 0, 0, 0][..], gen_float, 42.42),
365 Ok((vec![66, 41, 174, 20], 4))
366 );
367 }
368
369 #[test]
370 fn test_gen_double() {
371 assert_eq!(
372 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_double, 0.),
373 Ok((vec![0, 0, 0, 0, 0, 0, 0, 0], 8))
374 );
375 assert_eq!(
376 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_double, 42.42),
377 Ok((vec![64, 69, 53, 194, 143, 92, 40, 246], 8))
378 );
379 }
380
381 #[test]
382 fn test_gen_decimal_value() {
383 assert_eq!(
384 test_gen!(
385 &mut [0, 0, 0, 0, 0][..],
386 gen_decimal_value,
387 DecimalValue { scale: 0, value: 0 }
388 ),
389 Ok((vec![0, 0, 0, 0, 0], 5))
390 );
391 assert_eq!(
392 test_gen!(
393 &mut [0, 0, 0, 0, 0][..],
394 gen_decimal_value,
395 DecimalValue {
396 scale: 2,
397 value: 42
398 }
399 ),
400 Ok((vec![2, 0, 0, 0, 42], 5))
401 );
402 }
403
404 #[test]
405 fn test_gen_short_string() {
406 assert_eq!(
407 test_gen!(&mut [0][..], gen_short_string, ""),
408 Ok((vec![0], 1))
409 );
410 assert_eq!(
411 test_gen!(&mut [0, 0, 0, 0, 0][..], gen_short_string, "test"),
412 Ok((vec![4, 116, 101, 115, 116], 5))
413 );
414 }
415
416 #[test]
417 fn test_gen_long_string() {
418 assert_eq!(
419 test_gen!(&mut [0, 0, 0, 0][..], gen_long_string, &[]),
420 Ok((vec![0, 0, 0, 0], 4))
421 );
422 assert_eq!(
423 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_long_string, b"test"),
424 Ok((vec![0, 0, 0, 4, 116, 101, 115, 116], 8))
425 );
426 }
427
428 #[test]
429 fn test_gen_field_array() {
430 assert_eq!(
431 test_gen!(
432 &mut [0, 0, 0, 0][..],
433 gen_field_array,
434 &FieldArray::default()
435 ),
436 Ok((vec![0, 0, 0, 0], 4))
437 );
438 assert_eq!(
439 test_gen!(
440 &mut [0, 0, 0, 0, 0, 0][..],
441 gen_field_array,
442 &vec![AMQPValue::Boolean(true)].into()
443 ),
444 Ok((vec![0, 0, 0, 2, 116, 1], 6))
445 );
446 }
447
448 #[test]
449 fn test_gen_timestamp() {
450 assert_eq!(
451 test_gen!(&mut [0, 0, 0, 0, 0, 0, 0, 0][..], gen_timestamp, 0),
452 Ok((vec![0, 0, 0, 0, 0, 0, 0, 0], 8))
453 );
454 assert_eq!(
455 test_gen!(
456 &mut [0, 0, 0, 0, 0, 0, 0, 0][..],
457 gen_timestamp,
458 18446744073709551615
459 ),
460 Ok((vec![255, 255, 255, 255, 255, 255, 255, 255], 8))
461 );
462 }
463
464 #[test]
465 fn test_gen_field_table() {
466 let mut table = FieldTable::default();
467 table.insert("test".into(), AMQPValue::Float(42.42));
468 table.insert("test2".into(), AMQPValue::Boolean(false));
469 assert_eq!(
470 test_gen!(
471 &mut [0, 0, 0, 0][..],
472 gen_field_table,
473 &FieldTable::default()
474 ),
475 Ok((vec![0, 0, 0, 0], 4))
476 );
477 assert_eq!(
478 test_gen!(
479 &mut [
480 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
481 ][..],
482 gen_field_table,
483 &table
484 ),
485 Ok((
486 vec![
487 0, 0, 0, 18, 4, 116, 101, 115, 116, 102, 66, 41, 174, 20, 5, 116, 101, 115,
488 116, 50, 116, 0
489 ],
490 22
491 ))
492 );
493 }
494
495 #[test]
496 fn test_gen_byte_array() {
497 assert_eq!(
498 test_gen!(&mut [0, 0, 0, 0][..], gen_byte_array, &ByteArray::default()),
499 Ok((vec![0, 0, 0, 0], 4))
500 );
501 assert_eq!(
502 test_gen!(
503 &mut [0, 0, 0, 0, 0, 0, 0, 0][..],
504 gen_byte_array,
505 &vec![42, 1, 2, 3].into()
506 ),
507 Ok((vec![0, 0, 0, 4, 42, 1, 2, 3], 8))
508 );
509 }
510
511 #[test]
512 fn test_gen_flags() {
513 let mut flags = AMQPFlags::default();
514 flags.add_flag("a".to_string(), true);
515 flags.add_flag("b".to_string(), false);
516 flags.add_flag("c".to_string(), true);
517 flags.add_flag("d".to_string(), true);
518 assert_eq!(
519 test_gen!(&mut [0][..], gen_flags, &flags),
520 Ok((vec![0b00001101], 1))
521 );
522 flags.add_flag("e".to_string(), true);
523 flags.add_flag("f".to_string(), false);
524 flags.add_flag("g".to_string(), true);
525 flags.add_flag("h".to_string(), true);
526 flags.add_flag("i".to_string(), false);
527 flags.add_flag("j".to_string(), true);
528 assert_eq!(
529 test_gen!(&mut [0, 0][..], gen_flags, &flags),
530 Ok((vec![0b11011101, 0b00000010], 2))
531 );
532 }
533}