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}