index_fixed/
lib.rs

1#![no_std]
2#![forbid(unsafe_code)]
3
4#[doc(hidden)]
5pub use core::convert::TryInto;
6
7/**
8 * Slices (via the Index trait & operation) into fixed size arrays
9 *
10 * Will panic with the same rules as normal slicing.
11 *
12 * Will not compile if bounds are not static.
13 *
14 * Will not compile if end bound proceeds start bound.
15 *
16 * # Format
17 *
18 * ```notest
19 * index_fixed! ( {&,&mut} <slice> ; .. <end>)
20 * index_fixed! ( {&,&mut} <slice> ; <start> , .. <end>)
21 * index_fixed! ( {&,&mut} <slice> ; <start> , ... <end>)
22 * ```
23 *
24 * # Examples
25 *
26 * ```
27 * #[macro_use]
28 * extern crate index_fixed;
29 *
30 * fn main() {
31 *   let my_slice = [1, 2, 3, 4];
32 *   let slice_of_2 = index_fixed!(&my_slice ; .. 2);
33 *   assert_eq!(slice_of_2, &my_slice[..2]);
34 * }
35 * ```
36 */
37// FIXME example test disabled because index_fixed!() is not defined
38#[macro_export]
39macro_rules! index_fixed {
40    (&mut $s:expr ;  .. $e:expr) => {
41        index_fixed!(&mut $s; 0 , .. $e )
42    };
43    (&mut $s:expr ; $b:expr , ... $e:expr) => {
44        index_fixed!(&mut $s; $b , .. ($e + 1))
45    };
46    (&mut $s:expr ; $b:expr , .. $e:expr) => { {
47        fn conv<T>(b: &mut[T]) -> &mut[T;$e - $b] {
48            use $crate::TryInto;
49            b.try_into().unwrap()
50        }
51        conv(&mut $s[$b..$e])
52    } };
53    (& $s:expr ; .. $e:expr) => {
54        index_fixed!(& $s ; 0 , .. $e)
55    };
56    (& $s:expr ; $b:expr , ... $e:expr) => {
57        index_fixed!(& $s ; $b , .. ($e + 1))
58    };
59    (& $s:expr ; $b:expr , .. $e:expr) => { {
60        fn conv<T>(b: &[T]) -> &[T;$e - $b] {
61            use $crate::TryInto;
62            b.try_into().unwrap()
63        }
64        conv(& $s[$b..$e])
65    } };
66}
67
68/**
69 * `slice::get` and `slice::get_mut`, but return an `Option<&[T;N]>` or `Option<&mut [T;N]>`
70 *
71 * Will not compile if bounds are not static.
72 *
73 * Will not compile if end bound proceeds start bound.
74 *
75 * # Format
76 *
77 * ```notest
78 * index_fixed_get! ( {&,&mut} <slice> ; .. <end>)
79 * index_fixed_get! ( {&,&mut} <slice> ; <start> , .. <end>)
80 * index_fixed_get! ( {&,&mut} <slice> ; <start> , ... <end>)
81 * ```
82 *
83 * # Examples
84 *
85 * ```
86 * #[macro_use]
87 * extern crate index_fixed;
88 *
89 * fn main() {
90 *   let my_slice = [1, 2, 3, 4];
91 *   let slice_of_2 = index_fixed_get!(&my_slice ; .. 2);
92 *   assert_eq!(slice_of_2, Some(&[1,2]));
93 * }
94 * ```
95 */
96#[macro_export]
97macro_rules! index_fixed_get {
98    (&mut $s:expr ;  .. $e:expr) => {
99        index_fixed_get!(&mut $s; 0 , .. $e )
100    };
101    (&mut $s:expr ; $b:expr , ... $e:expr) => {
102        index_fixed_get!(&mut $s; $b , .. ($e + 1))
103    };
104    (&mut $s:expr ; $b:expr , .. $e:expr) => { {
105        fn conv<T>(a: Option<&mut[T]>) -> Option<&mut[T;$e - $b]> {
106            a.map(|b| {
107                  use $crate::TryInto;
108                  b.try_into().unwrap()
109            })
110        }
111        conv($s.get_mut($b..$e))
112    } };
113    (& $s:expr ; .. $e:expr) => {
114        index_fixed_get!(& $s ; 0 , .. $e)
115    };
116    (& $s:expr ; $b:expr , ... $e:expr) => {
117        index_fixed_get!(& $s ; $b , .. ($e + 1))
118    };
119    (& $s:expr ; $b:expr , .. $e:expr) => { {
120        fn conv<T>(a: Option<&[T]>) -> Option<&[T;$e - $b]> {
121            a.map(|b| {
122                  use $crate::TryInto;
123                  b.try_into().unwrap()
124            })
125        }
126        conv($s.get($b..$e))
127    } };
128}