cookie_factory/
gen.rs

1//! legacy serializers, kept for backwards compatibility from previous cookie factory versions
2
3use crate::bytes::*;
4use crate::internal::*;
5use crate::lib::std::io;
6
7pub fn legacy_wrap<'a, G>(
8    gen: G,
9    x: (&'a mut [u8], usize),
10) -> Result<(&'a mut [u8], usize), GenError>
11where
12    G: SerializeFn<io::Cursor<&'a mut [u8]>>,
13{
14    let (buf, offset) = x;
15    let (buf, offset) = {
16        let mut cursor = io::Cursor::new(buf);
17        cursor.set_position(offset as u64);
18        let cursor = gen_simple(gen, cursor)?;
19        let position = cursor.position();
20        (cursor.into_inner(), position)
21    };
22    Ok((buf, offset as usize))
23}
24
25/// Write an unsigned 1 byte integer. Equivalent to `gen_be_u8!(v)`
26#[inline]
27pub fn set_be_u8(x: (&mut [u8], usize), v: u8) -> Result<(&mut [u8], usize), GenError> {
28    legacy_wrap(be_u8(v), x)
29}
30
31/// Write an unsigned 2 bytes integer (big-endian order). Equivalent to `gen_be_u16!(v)`
32#[inline]
33pub fn set_be_u16(x: (&mut [u8], usize), v: u16) -> Result<(&mut [u8], usize), GenError> {
34    legacy_wrap(be_u16(v), x)
35}
36
37/// Write an unsigned 4 bytes integer (big-endian order). Equivalent to `gen_be_u32!(v)`
38#[inline]
39pub fn set_be_u32(x: (&mut [u8], usize), v: u32) -> Result<(&mut [u8], usize), GenError> {
40    legacy_wrap(be_u32(v), x)
41}
42
43/// Write an unsigned 8 bytes integer (big-endian order). Equivalent to `gen_be_u64!(v)`
44#[inline]
45pub fn set_be_u64(x: (&mut [u8], usize), v: u64) -> Result<(&mut [u8], usize), GenError> {
46    legacy_wrap(be_u64(v), x)
47}
48
49/// Write an unsigned 1 byte integer. Equivalent to `gen_le_u8!(v)`
50#[inline]
51pub fn set_le_u8(x: (&mut [u8], usize), v: u8) -> Result<(&mut [u8], usize), GenError> {
52    legacy_wrap(le_u8(v), x)
53}
54
55/// Write an unsigned 2 bytes integer (little-endian order). Equivalent to `gen_le_u16!(v)`
56#[inline]
57pub fn set_le_u16(x: (&mut [u8], usize), v: u16) -> Result<(&mut [u8], usize), GenError> {
58    legacy_wrap(le_u16(v), x)
59}
60
61/// Write an unsigned 4 bytes integer (little-endian order). Equivalent to `gen_le_u32!(v)`
62#[inline]
63pub fn set_le_u32(x: (&mut [u8], usize), v: u32) -> Result<(&mut [u8], usize), GenError> {
64    legacy_wrap(le_u32(v), x)
65}
66
67/// Write an unsigned 8 bytes integer (little-endian order). Equivalent to `gen_le_u64!(v)`
68#[inline]
69pub fn set_le_u64(x: (&mut [u8], usize), v: u64) -> Result<(&mut [u8], usize), GenError> {
70    legacy_wrap(le_u64(v), x)
71}
72
73/// `gen_align!(I, u8) => I -> Result<I,E>`
74/// Align the output buffer to the next multiple of specified value.
75///
76/// Does not modify the output buffer, but increments the output index.
77#[macro_export]
78macro_rules! gen_align(
79    (($i:expr, $idx:expr), $val:expr) => (
80        {
81            let aligned = $val - ($idx % $val);
82            match $i.len() <= $idx+aligned {
83                true  => Err(GenError::BufferTooSmall($idx+aligned - $i.len())),
84                false => { Ok(($i,($idx+aligned))) },
85            }
86        }
87    );
88    ($i:expr, $val:expr) => ( gen_align!(($i.0, $i.1), $val) );
89);
90
91/// `gen_skip!(I, u8) => I -> Result<I,E>`
92/// Skip the specified number of bytes.
93///
94/// Does not modify the output buffer, but increments the output index.
95#[macro_export]
96macro_rules! gen_skip(
97    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::combinator::skip($val as usize), $i) );
98);
99
100/// `gen_be_u8!(I, u8) => I -> Result<I,E>`
101/// Write an unsigned 1 byte integer.
102#[macro_export]
103macro_rules! gen_be_u8(
104    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u8($val), $i) );
105);
106
107/// `gen_be_u16!(I, u8) => I -> Result<I,E>`
108/// Write an unsigned 2 bytes integer (using big-endian order).
109#[macro_export]
110macro_rules! gen_be_u16(
111    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u16($val), $i) );
112);
113
114/// `gen_be_u24!(I, u8) => I -> Result<I,E>`
115/// Write an unsigned 3 bytes integer (using big-endian order).
116#[macro_export]
117macro_rules! gen_be_u24(
118    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u24($val), $i) );
119);
120
121/// `gen_be_u32!(I, u8) => I -> Result<I,E>`
122/// Write an unsigned 4 bytes integer (using big-endian order).
123#[macro_export]
124macro_rules! gen_be_u32(
125    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u32($val), $i) );
126);
127
128/// `gen_be_u64!(I, u8) => I -> Result<I,E>`
129/// Write an unsigned 8 bytes integer (using big-endian order).
130/// ```rust,ignore
131///  let r = gen_be_u64!((&mut mem,0),0x0102030405060708u64);
132/// ```
133#[macro_export]
134macro_rules! gen_be_u64(
135    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_u64($val), $i) );
136);
137
138/// `gen_be_i8!(I, i8) => I -> Result<I,E>`
139/// Write a signed 1 byte integer.
140#[macro_export]
141macro_rules! gen_be_i8(
142    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i8($val), $i) );
143);
144
145/// `gen_be_i16!(I, i16) => I -> Result<I,E>`
146/// Write a signed 2 byte integer.
147#[macro_export]
148macro_rules! gen_be_i16(
149    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i16($val), $i) );
150);
151
152/// `gen_be_i24!(I, i24) => I -> Result<I,E>`
153/// Write a signed 3 byte integer.
154#[macro_export]
155macro_rules! gen_be_i24(
156    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i24($val), $i) );
157);
158
159/// `gen_be_i32!(I, i32) => I -> Result<I,E>`
160/// Write a signed 4 byte integer.
161#[macro_export]
162macro_rules! gen_be_i32(
163    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i32($val), $i) );
164);
165
166/// `gen_be_i64!(I, i64) => I -> Result<I,E>`
167/// Write a signed 8 byte integer.
168#[macro_export]
169macro_rules! gen_be_i64(
170    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_i64($val), $i) );
171);
172
173/// `gen_be_f32!(I, f32) => I -> Result<I,E>`
174/// Write a 4 byte float.
175#[macro_export]
176macro_rules! gen_be_f32(
177    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_f32($val), $i) );
178);
179
180/// `gen_be_f64!(I, f64) => I -> Result<I,E>`
181/// Write a 8 byte float.
182#[macro_export]
183macro_rules! gen_be_f64(
184    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::be_f64($val), $i) );
185);
186
187/// `gen_le_u8!(I, u8) => I -> Result<I,E>`
188/// Write an unsigned 1 byte integer.
189#[macro_export]
190macro_rules! gen_le_u8(
191    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u8($val), $i) );
192);
193
194/// `gen_le_u16!(I, u8) => I -> Result<I,E>`
195/// Write an unsigned 2 bytes integer (using little-endian order).
196#[macro_export]
197macro_rules! gen_le_u16(
198    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u16($val), $i) );
199);
200
201/// `gen_le_u24!(I, u8) => I -> Result<I,E>`
202/// Write an unsigned 3 bytes integer (using little-endian order).
203#[macro_export]
204macro_rules! gen_le_u24(
205    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u24($val), $i) );
206);
207
208/// `gen_le_u32!(I, u8) => I -> Result<I,E>`
209/// Write an unsigned 4 bytes integer (using little-endian order).
210#[macro_export]
211macro_rules! gen_le_u32(
212    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u32($val), $i) );
213);
214
215/// `gen_le_u64!(I, u8) => I -> Result<I,E>`
216/// Write an unsigned 8 bytes integer (using little-endian order).
217/// ```rust,ignore
218///  let r = gen_le_u64!((&mut mem,0),0x0102030405060708u64);
219/// ```
220#[macro_export]
221macro_rules! gen_le_u64(
222    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_u64($val), $i) );
223);
224
225/// `gen_le_i8!(I, i8) => I -> Result<I,E>`
226/// Write a signed 1 byte integer.
227#[macro_export]
228macro_rules! gen_le_i8(
229    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i8($val), $i) );
230);
231
232/// `gen_le_i16!(I, i16) => I -> Result<I,E>`
233/// Write a signed 2 byte integer.
234#[macro_export]
235macro_rules! gen_le_i16(
236    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i16($val), $i) );
237);
238
239/// `gen_le_i24!(I, i24) => I -> Result<I,E>`
240/// Write a signed 3 byte integer.
241#[macro_export]
242macro_rules! gen_le_i24(
243    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i24($val), $i) );
244);
245
246/// `gen_le_i32!(I, i32) => I -> Result<I,E>`
247/// Write a signed 4 byte integer.
248#[macro_export]
249macro_rules! gen_le_i32(
250    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i32($val), $i) );
251);
252
253/// `gen_le_i64!(I, i64) => I -> Result<I,E>`
254/// Write a signed 8 byte integer.
255#[macro_export]
256macro_rules! gen_le_i64(
257    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_i64($val), $i) );
258);
259
260/// `gen_le_f32!(I, f32) => I -> Result<I,E>`
261/// Write a 4 byte float.
262#[macro_export]
263macro_rules! gen_le_f32(
264    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_f32($val), $i) );
265);
266
267/// `gen_le_f64!(I, f64) => I -> Result<I,E>`
268/// Write a 8 byte float.
269#[macro_export]
270macro_rules! gen_le_f64(
271    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::bytes::le_f64($val), $i) );
272);
273
274/// `gen_copy!(I, &[u8], u8) => I -> Result<I,E>`
275/// Writes a slice, copying only the specified number of bytes to the output buffer.
276#[macro_export]
277macro_rules! gen_copy(
278    (($i:expr, $idx:expr), $val:expr, $l:expr) => (
279        match $i.len() < $idx+$l {
280            true  => Err(GenError::BufferTooSmall($idx+$l - $i.len())),
281            false => {
282                $i[$idx..$idx+$l].clone_from_slice(&$val[0..$l]);
283                Ok(($i,($idx+$l)))
284            }
285        }
286    );
287    ($i:expr, $val:expr, $l:expr) => ( gen_copy!(($i.0,$i.1), $val, $l) );
288);
289
290/// `gen_slice!(I, &[u8]) => I -> Result<I,E>`
291/// Writes a slice, copying it entirely to the output buffer.
292#[macro_export]
293macro_rules! gen_slice(
294    ($i:expr, $val:expr) => ( $crate::gen::legacy_wrap($crate::combinator::slice($val), $i) );
295);
296
297#[macro_export]
298macro_rules! gen_length_slice(
299    (($i:expr, $idx:expr), $lf:ident, $val:expr) => (
300        do_gen!(($i,$idx),
301            $lf($val.len()) >>
302            gen_slice!($val)
303        )
304    );
305    (($i:expr, $idx:expr), $lsubmac:ident >> $val:expr) => (
306        do_gen!(($i,$idx),
307            $lsubmac!($val.len()) >>
308            gen_slice!($val)
309        )
310    );
311);
312
313/// Used to wrap common expressions and function as macros
314///
315/// ```rust,no_run
316/// # #[macro_use] extern crate cookie_factory;
317/// # use cookie_factory::{*, gen::set_be_u8};
318/// # fn main() {
319/// // will make a generator setting an u8
320/// fn gen0(x:(&mut [u8],usize),v:u8) -> Result<(&mut [u8],usize),GenError> {
321///   gen_call!((x.0,x.1), set_be_u8, v)
322/// }
323/// # }
324/// ```
325#[macro_export]
326macro_rules! gen_call(
327    (($i:expr, $idx:expr), $fun:expr) => ( $fun( ($i,$idx) ) );
328    (($i:expr, $idx:expr), $fun:expr, $($args:expr),* ) => ( $fun( ($i,$idx), $($args),* ) );
329);
330
331/// Applies sub-generators in a sequence.
332///
333/// `do_gen!( I,
334///          I -> Result<I,E> >> I-> Result<I,E> >> ... >> I->Result<I,E>)
335///     => I -> Result<I,E>
336/// with I = (&[u8],usize) and E = GenError
337/// `
338///
339/// The input type is a tuple (slice,index). The index is incremented by each generator, to reflect
340/// the number of bytes written.
341///
342/// If the input slice is not big enough, an error `GenError::BufferTooSmall(n)` is returned, `n`
343/// being the index that was required.
344///
345/// ```rust,no_run
346/// # #[macro_use] extern crate cookie_factory;
347/// # use cookie_factory::*;
348///
349/// fn gen0(x:(&mut [u8],usize),v:u8,w:u8) -> Result<(&mut [u8],usize),GenError> {
350///   do_gen!((x.0,x.1), gen_be_u8!(v) >> gen_be_u8!(w))
351/// }
352///
353/// # fn main() {
354/// let mut mem : [u8; 2] = [0; 2];
355/// let s = &mut mem[..];
356/// let expected = [1, 2];
357///
358/// match gen0((s,0), 1, 2) {
359///     Ok((b,idx)) => {
360///         assert_eq!(idx,expected.len());
361///         assert_eq!(&b[..],&expected[..]);
362///     },
363///     Err(e) => panic!("error {:?}",e),
364/// }
365/// # }
366/// ```
367#[macro_export]
368macro_rules! do_gen(
369    (__impl $i:expr, $idx:expr, ( $($rest:expr),* )) => (
370        {
371            $($rest)*;
372            Ok(($i,$idx))
373        }
374    );
375    (__impl $i:expr, $idx:expr, $e:ident( $($args:tt)* )) => (
376        do_gen!(__impl $i, $idx, gen_call!($e,$($args)*))
377    );
378    (__impl $i:expr, $idx:expr, $submac:ident!( $($args:tt)* )) => (
379        $submac!(($i,$idx), $($args)*)
380    );
381
382    (__impl $i:expr, $idx:expr, $e:ident >> $($rest:tt)*) => (
383        do_gen!(__impl $i, $idx, gen_call!($e) >> $($rest)*)
384    );
385    (__impl $i:expr, $idx:expr, $e:ident( $($args:tt)* ) >> $($rest:tt)*) => (
386        do_gen!(__impl $i, $idx, gen_call!($e,$($args)*) >> $($rest)*)
387    );
388    (__impl $i:expr, $idx:expr, $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => (
389        {
390            match $submac!(($i,$idx), $($args)*) {
391                Ok((j,idx2)) => {
392                    do_gen!(__impl j, idx2, $($rest)*)
393                },
394                Err(e) => Err(e),
395            }
396        }
397    );
398
399    (__impl $i:expr, $idx:expr, $e:ident : $($rest:tt)*) => (
400        {
401            let $e = $idx;
402            do_gen!(__impl $i, $idx, $($rest)*)
403        }
404    );
405
406    ( ($i:expr, $idx:expr), $($rest:tt)*) => (
407        do_gen!(__impl $i, $idx, $($rest)*)
408    );
409    ( $i:expr, $($rest:tt)*) => (
410        do_gen!(__impl $i.0, $i.1, $($rest)*)
411    );
412);
413
414/// `gen_cond!(bool, I -> Result<I,E>) => I -> Result<I,E>`
415/// Conditional combinator
416///
417/// Wraps another generator and calls it if the
418/// condition is met. This combinator returns
419/// the return value of the child generator.
420///
421#[macro_export]
422macro_rules! gen_cond(
423    (($i:expr, $idx:expr), $cond:expr, $submac:ident!( $($args:tt)* )) => (
424        {
425            if $cond {
426                $submac!(($i,$idx), $($args)*)
427            } else {
428                Ok(($i,$idx))
429            }
430        }
431    );
432    (($i:expr, $idx:expr), $cond:expr, $f:expr) => (
433        gen_cond!(($i,$idx), $cond, gen_call!($f))
434    );
435);
436
437/// `gen_if_else!(bool, I -> Result<I,E>, I -> Result<I,E>) => I -> Result<I,E>`
438/// Conditional combinator, with alternate generator.
439///
440/// Wraps another generator and calls it if the
441/// condition is met. This combinator returns
442/// the return value of the child generator.
443///
444/// If the condition is not satisfied, calls the alternate generator.
445///
446#[macro_export]
447macro_rules! gen_if_else(
448    (($i:expr, $idx:expr), $cond:expr, $submac_if:ident!( $($args_if:tt)* ), $submac_else:ident!( $($args_else:tt)* )) => (
449        {
450            if $cond {
451                $submac_if!(($i,$idx), $($args_if)*)
452            } else {
453                $submac_else!(($i,$idx), $($args_else)*)
454            }
455        }
456    );
457    (($i:expr, $idx:expr), $cond:expr, $f:expr, $g:expr) => (
458        gen_cond!(($i,$idx), $cond, gen_call!($f), gen_call!($g))
459    );
460);
461
462/// `gen_many_ref!(I, Iterable<V>, Fn(I,V)) => I -> Result<I,E>`
463/// Applies the generator `$f` to every element of `$l`, passing arguments by reference.
464#[macro_export]
465macro_rules! gen_many_ref(
466    (($i:expr, $idx:expr), $l:expr, $f:expr) => (
467        $l.into_iter().fold(
468            Ok(($i,$idx)),
469            |r,ref v| {
470                match r {
471                    Err(e) => Err(e),
472                    Ok(x) => { $f(x, v) },
473                }
474            }
475        )
476    );
477);
478
479/// `gen_many_byref!(I, Iterable<V>, Fn(I,V)) => I -> Result<I,E>`
480/// Applies the generator `$f` to every element of `$l`, where arguments of $l are references
481#[macro_export]
482macro_rules! gen_many_byref(
483    (($i:expr, $idx:expr), $l:expr, $f:expr) => (
484        $l.into_iter().fold(
485            Ok(($i,$idx)),
486            |r,&v| {
487                match r {
488                    Err(e) => Err(e),
489                    Ok(x) => { $f(x, v) },
490                }
491            }
492        )
493    );
494);
495
496/// `gen_many!(I, Iterable<V>, Fn(I,V)) => I -> Result<I,E>`
497/// Applies the generator `$f` to every element of `$l`, passing arguments by value.
498#[macro_export]
499macro_rules! gen_many(
500    (($i:expr, $idx:expr), $l:expr, $f:expr) => (
501        $l.into_iter().fold(
502            Ok(($i,$idx)),
503            |r,v| {
504                match r {
505                    Err(e) => Err(e),
506                    Ok(x) => { $f(x, v) },
507                }
508            }
509        )
510    );
511);
512
513/// `gen_at_offset!(usize, I -> Result<I,E>) => I -> Result<I,E>`
514/// Combinator to call generator at an absolute offset.
515///
516/// Wraps another generator and calls it using a different index
517/// from the current position. If this combinator succeeds, it returns
518/// the current index (instead of the one returned by the child generator).
519/// If the child generator fails, returns the error.
520///
521#[macro_export]
522macro_rules! gen_at_offset(
523    (($i:expr, $idx:expr), $offset:expr, $f:ident( $($args:tt)* )) => (
524        match $i.len() < $offset {
525            false => {
526                match $f(($i,$offset), $($args)*) {
527                    Ok((r,_)) => Ok((r,($idx))),
528                    Err(e)    => Err(e),
529                }
530            },
531            true  => Err(GenError::BufferTooSmall($offset - $i.len())),
532        }
533    );
534    (($i:expr, $idx:expr), $offset:expr, $submac:ident!( $($args:tt)* )) => (
535        match $i.len() < $offset {
536            false => {
537                match $submac!(($i,$offset), $($args)*) {
538                    Ok((r,_)) => Ok((r,($idx))),
539                    Err(e)    => Err(e),
540                }
541            },
542            true  => Err(GenError::BufferTooSmall($offset - $i.len())),
543        }
544    );
545);
546
547/// `gen_at_offset!(usize, I -> Result<I,E>) => I -> Result<I,E>`
548/// Combinator to call generator at a relative offset.
549///
550/// Wraps another generator and calls it using a different index
551/// from the current position. If this combinator succeeds, it returns
552/// the current index (instead of the one returned by the child generator).
553/// If the child generator fails, returns the error.
554///
555#[macro_export]
556macro_rules! gen_at_rel_offset(
557    (($i:expr, $idx:expr), $rel_offset:expr, $f:ident( $($args:tt)* )) => (
558        match ($rel_offset as i32).overflowing_add($idx as i32).1 {
559            (s,false) if s > 0 => { gen_at_offset!(($i,$idx),s as usize,$f($($args)*)) },
560            _                  => Err(GenError::InvalidOffset),
561        }
562    );
563    (($i:expr, $idx:expr), $rel_offset:expr, $submac:ident!( $($args:tt)* )) => (
564        match ($rel_offset as i32).overflowing_add($idx as i32) {
565            (s,false) if s > 0 => { gen_at_offset!(($i,$idx),s as usize,$submac!($($args)*)) },
566            _                  => Err(GenError::InvalidOffset),
567        }
568    );
569);
570
571#[cfg(test)]
572mod tests {
573    use super::*;
574
575    #[test]
576    fn test_do_gen() {
577        let mut mem: [u8; 8] = [0; 8];
578        let s = &mut mem[..];
579        let expected = [1, 2, 3, 4, 5, 6, 7, 8];
580        let r = do_gen!(
581            (s, 0),
582            gen_be_u8!(1) >> gen_be_u8!(2) >> gen_be_u16!(0x0304) >> gen_be_u32!(0x05060708)
583        );
584        match r {
585            Ok((b, idx)) => {
586                assert_eq!(idx, 8);
587                assert_eq!(b, &expected);
588            }
589            Err(e) => panic!("error {:?}", e),
590        }
591    }
592
593    #[test]
594    fn test_do_gen_vector() {
595        let mut data = [0; 8];
596        let expected = [1, 2, 3, 4, 5, 6, 7, 8];
597        let r = do_gen!(
598            (&mut data, 0),
599            gen_be_u8!(1) >> gen_be_u8!(2) >> gen_be_u16!(0x0304) >> gen_be_u32!(0x05060708)
600        );
601        match r {
602            Ok((b, idx)) => {
603                assert_eq!(idx, 8);
604                assert_eq!(b, &expected);
605            }
606            Err(e) => panic!("error {:?}", e),
607        }
608    }
609
610    #[test]
611    fn test_gen_skip() {
612        let mut mem: [u8; 8] = [0; 8];
613        let s = &mut mem[..];
614        let expected = [0, 0, 0, 0, 0, 0, 0, 0];
615        let r = gen_skip!((s, 0), 5);
616        match r {
617            Ok((b, idx)) => {
618                assert_eq!(idx, 5);
619                assert_eq!(b, &expected);
620            }
621            Err(e) => panic!("error {:?}", e),
622        }
623    }
624
625    #[test]
626    fn test_gen_be_u8() {
627        let mut mem: [u8; 8] = [0; 8];
628        let s = &mut mem[..];
629        let expected = [1, 2, 0, 0, 0, 0, 0, 0];
630        let r = do_gen!((s, 0), gen_be_u8!(1) >> gen_be_u8!(2));
631        match r {
632            Ok((b, idx)) => {
633                assert_eq!(idx, 2);
634                assert_eq!(b, &expected);
635            }
636            Err(e) => panic!("error {:?}", e),
637        }
638    }
639
640    #[test]
641    fn test_gen_le_u8() {
642        let mut mem: [u8; 8] = [0; 8];
643        let s = &mut mem[..];
644        let expected = [1, 2, 0, 0, 0, 0, 0, 0];
645        let r = do_gen!((s, 0), gen_le_u8!(1) >> gen_le_u8!(2));
646        match r {
647            Ok((b, idx)) => {
648                assert_eq!(idx, 2);
649                assert_eq!(b, &expected);
650            }
651            Err(e) => panic!("error {:?}", e),
652        }
653    }
654
655    #[test]
656    fn test_gen_be_i32() {
657        let mut mem: [u8; 8] = [0; 8];
658        let expected = [0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0];
659        let r = gen_be_i32!((&mut mem, 0), -1i32);
660        match r {
661            Ok((b, idx)) => {
662                assert_eq!(idx, 4);
663                assert_eq!(b, &expected);
664            }
665            Err(e) => panic!("error {:?}", e),
666        }
667    }
668
669    #[test]
670    fn test_gen_be_u64() {
671        let mut mem: [u8; 8] = [0; 8];
672        let expected = [1, 2, 3, 4, 5, 6, 7, 8];
673        let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
674        match r {
675            Ok((b, idx)) => {
676                assert_eq!(idx, 8);
677                assert_eq!(b, &expected);
678            }
679            Err(e) => panic!("error {:?}", e),
680        }
681    }
682
683    #[test]
684    fn test_gen_be_u64_very_short_buffer() {
685        let mut mem = [0; 3];
686
687        let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
688        match r {
689            Ok((b, idx)) => panic!("should have failed, but wrote {} bytes: {:?}", idx, b),
690            Err(GenError::BufferTooSmall(sz)) => assert_eq!(sz, 5),
691            Err(e) => panic!("error {:?}", e),
692        }
693    }
694
695    #[test]
696    fn test_gen_be_u64_slightly_short_buffer() {
697        let mut mem = [0; 7];
698        let r = gen_be_u64!((&mut mem, 0), 0x0102030405060708u64);
699        match r {
700            Ok((b, idx)) => panic!("should have failed, but wrote {} bytes: {:?}", idx, b),
701            Err(GenError::BufferTooSmall(sz)) => assert_eq!(sz, 1),
702            Err(e) => panic!("error {:?}", e),
703        }
704    }
705
706    #[test]
707    fn test_gen_le_u64() {
708        let mut mem: [u8; 8] = [0; 8];
709        let expected = [8, 7, 6, 5, 4, 3, 2, 1];
710        let r = gen_le_u64!((&mut mem, 0), 0x0102030405060708u64);
711        match r {
712            Ok((b, idx)) => {
713                assert_eq!(idx, 8);
714                assert_eq!(b, &expected);
715            }
716            Err(e) => panic!("error {:?}", e),
717        }
718    }
719
720    #[test]
721    fn test_set_be_u8() {
722        let mut mem: [u8; 8] = [0; 8];
723        let s = &mut mem[..];
724        let expected = [1, 2, 0, 0, 0, 0, 0, 0];
725        let r = do_gen!((s, 0), set_be_u8(1) >> set_be_u8(2));
726        match r {
727            Ok((b, idx)) => {
728                assert_eq!(idx, 2);
729                assert_eq!(b, &expected);
730            }
731            Err(e) => panic!("error {:?}", e),
732        }
733    }
734
735    #[test]
736    fn test_gen_align() {
737        let mut mem: [u8; 8] = [0; 8];
738        let s = &mut mem[..];
739        let expected = [1, 0, 0, 0, 1, 0, 0, 0];
740        let r = do_gen!((s, 0), gen_be_u8!(1) >> gen_align!(4) >> gen_be_u8!(1));
741        match r {
742            Ok((b, idx)) => {
743                assert_eq!(idx, 5);
744                assert_eq!(b, &expected);
745            }
746            Err(e) => panic!("error {:?}", e),
747        }
748    }
749
750    #[test]
751    #[cfg(feature = "std")]
752    fn test_gen_many() {
753        let mut mem: [u8; 8] = [0; 8];
754        let s = &mut mem[..];
755        let v: Vec<u16> = vec![1, 2, 3, 4];
756        let expected = [0, 1, 0, 2, 0, 3, 0, 4];
757        let r = gen_many!((s, 0), v, set_be_u16);
758        match r {
759            Ok((b, idx)) => {
760                assert_eq!(idx, 8);
761                assert_eq!(b, &expected);
762            }
763            Err(e) => panic!("error {:?}", e),
764        }
765    }
766
767    #[test]
768    fn test_gen_copy() {
769        let mut mem: [u8; 8] = [0; 8];
770        let s = &mut mem[..];
771        let v = [1, 2, 3, 4];
772        let expected = [1, 2, 3, 4, 0, 0, 0, 0];
773        let r = gen_copy!((s, 0), v, v.len());
774        match r {
775            Ok((b, idx)) => {
776                assert_eq!(idx, 4);
777                assert_eq!(b, &expected);
778            }
779            Err(e) => panic!("error {:?}", e),
780        }
781    }
782
783    #[test]
784    fn test_gen_copy_buffer_too_small() {
785        let mut mem: [u8; 7] = [0; 7];
786        let s = &mut mem[..];
787        let v = [0, 1, 2, 3, 4, 5, 6, 7];
788        let r = gen_copy!((s, 0), v, v.len());
789        match r {
790            Ok(_) => {
791                panic!("buffer shouldn't have had enough space");
792            }
793            Err(GenError::BufferTooSmall(sz)) => {
794                if sz != 1 {
795                    panic!("invalid max index returned, expected {} got {}", 1, sz);
796                }
797            }
798            Err(e) => {
799                panic!("error {:?}", e);
800            }
801        }
802    }
803
804    #[test]
805    fn test_gen_slice() {
806        let mut mem: [u8; 0] = [0; 0];
807        let s = &mut mem[..];
808        let v = [];
809        let expected = [];
810        let r = gen_slice!((s, 0), v);
811        match r {
812            Ok((b, idx)) => {
813                assert_eq!(idx, 0);
814                assert_eq!(b, &expected);
815            }
816            Err(e) => panic!("error {:?}", e),
817        }
818    }
819
820    #[test]
821    fn test_gen_slice_buffer_too_small() {
822        let mut mem: [u8; 7] = [0; 7];
823        let s = &mut mem[..];
824        let v = [0, 1, 2, 3, 4, 5, 6, 7];
825        let r = gen_slice!((s, 0), v);
826        match r {
827            Ok(_) => {
828                panic!("buffer shouldn't have had enough space");
829            }
830            Err(GenError::BufferTooSmall(sz)) => {
831                if sz != 1 {
832                    panic!("invalid max index returned, expected {} got {}", 1, sz);
833                }
834            }
835            Err(e) => {
836                panic!("error {:?}", e);
837            }
838        }
839    }
840
841    #[test]
842    fn test_gen_length_slice() {
843        let mut mem: [u8; 8] = [0; 8];
844        let s = &mut mem[..];
845        let v = [1, 2, 3, 4];
846        let expected = [0, 4, 1, 2, 3, 4, 0, 0];
847        macro_rules! gen_be_usize_as_u16(
848            ($i:expr, $val:expr) => ( set_be_u16($i, $val as u16) );
849        );
850        let r = do_gen!((s, 0), gen_length_slice!(gen_be_usize_as_u16 >> v));
851        match r {
852            Ok((b, idx)) => {
853                assert_eq!(idx, 6);
854                assert_eq!(b, &expected);
855            }
856            Err(e) => panic!("error {:?}", e),
857        }
858    }
859
860    #[test]
861    fn test_gen_checkpoint() {
862        let mut mem: [u8; 8] = [0; 8];
863        let s = &mut mem[..];
864        let expected = [1, 0, 0, 0, 0, 4, 0, 0];
865        let r = do_gen!(
866            (s, 0),
867            start: gen_be_u8!(1) >> gen_align!(4) >> end: gen_be_u16!((end - start) as u16)
868        );
869        match r {
870            Ok((b, idx)) => {
871                assert_eq!(idx, 6);
872                assert_eq!(b, &expected);
873            }
874            Err(e) => panic!("error {:?}", e),
875        }
876    }
877
878    #[test]
879    fn test_gen_at_offset() {
880        let mut mem: [u8; 8] = [0; 8];
881        let s = &mut mem[..];
882        let expected = [0, 0, 0, 0, 0, 4, 0, 0];
883        let r = do_gen!((s, 0), gen_skip!(2) >> gen_at_offset!(4, gen_be_u16!(4)));
884        match r {
885            Ok((b, idx)) => {
886                assert_eq!(idx, 2);
887                assert_eq!(b, &expected);
888            }
889            Err(e) => panic!("error {:?}", e),
890        }
891    }
892
893    #[test]
894    fn test_gen_at_rel_offset() {
895        let mut mem: [u8; 8] = [0; 8];
896        let s = &mut mem[..];
897        let expected = [0, 0, 0, 0, 0, 0, 0, 4];
898        let r = do_gen!(
899            (s, 0),
900            gen_skip!(2) >> gen_at_rel_offset!(4, gen_be_u16!(4))
901        );
902        match r {
903            Ok((b, idx)) => {
904                assert_eq!(idx, 2);
905                assert_eq!(b, &expected);
906            }
907            Err(e) => panic!("error {:?}", e),
908        }
909    }
910
911    #[test]
912    fn test_gen_at_rel_offset_fail() {
913        let mut mem: [u8; 8] = [0; 8];
914        let s = &mut mem[..];
915        let r = do_gen!(
916            (s, 0),
917            gen_skip!(2) >> gen_at_rel_offset!(-4, gen_be_u16!(4))
918        );
919        if let Err(GenError::InvalidOffset) = r {
920        } else {
921            panic!("unexpected result {:?}", r)
922        };
923    }
924}