structural/structural_aliases/
array_traits.rs

1/*!
2Traits (including structural aliases) for arrays.
3
4# `Array*` traits
5
6The `Array*` traits alias the accessor traits for arrays,
7with shared,mutable,and by value access to every element of the array.
8
9These traits can be used with any array at least as large as the size indicated
10by the trait.<br>
11You can,for example,use `Array3` with any array type from `[T;3]` to `[T;32]` inclusive.
12
13
14### Homogeneous tuples
15
16You can pass homogeneous tuples to functions expecting `Array*` implementing types.
17
18
19```
20use structural::structural_aliases::array_traits::Array4;
21use structural::{StructuralExt,fp};
22
23fn takes_array(array:impl Array4<u32>){
24    assert_eq!( array.field_(fp!(0)), &3 );
25    assert_eq!( array.field_(fp!(1)), &5 );
26    assert_eq!( array.field_(fp!(2)), &8 );
27    assert_eq!( array.field_(fp!(3)), &13 );
28}
29
30takes_array( (3,5,8,13) );
31
32// Tuples only have to be homogeneous up to the size of the expected array.
33takes_array( (3,5,8,13,"foo") );
34takes_array( (3,5,8,13,"foo",vec!["bar"]) );
35
36```
37
38# `Array*` Example
39
40```
41use structural::structural_aliases::array_traits::Array3;
42use structural::{StructuralExt,fp};
43
44use std::fmt::Debug;
45
46fn print_first_3<T>(array:impl Array3<T>)
47where
48    T:Debug,
49{
50    println!("{:?}",array.fields(fp!(0,1,2)))
51}
52
53print_first_3( [3,5,8] );
54print_first_3( [3,5,8,13] );
55print_first_3( [3,5,8,13,21]);
56print_first_3( [3,5,8,13,21,34] );
57print_first_3( ["foo";7] );
58print_first_3( ["bar";31] );
59print_first_3( ["baz";32] );
60
61
62
63```
64
65# `Array*Variant` Example
66
67Demonstrates that you can use the `Array*Variant` trait with enums.
68
69```
70use structural::structural_aliases::Array2Variant;
71use structural::{StructuralExt,Structural,TS,fp};
72
73use std::fmt::Debug;
74
75fn first_2<T>(mut foo:T, mut not_foo:T)
76where
77    T: Array2Variant<u8,TS!(Foo)> + Copy
78{
79    {
80        assert_eq!( foo.fields(fp!(::Foo=>0,1)), Some(( &101, &202 )) );
81
82        assert_eq!( foo.fields_mut(fp!(::Foo=>0,1)), Some(( &mut 101, &mut 202 )) );
83
84        assert_eq!( foo.into_field(fp!(::Foo.0)), Some(101) );
85        assert_eq!( foo.into_field(fp!(::Foo.1)), Some(202) );
86
87        assert_eq!( foo.is_variant(fp!(Foo)), true );
88    }
89    {
90        assert_eq!( not_foo.fields(fp!(::Foo=>0,1)), None );
91
92        assert_eq!( not_foo.fields_mut(fp!(::Foo=>0,1)), None );
93
94        assert_eq!( not_foo.into_field(fp!(::Foo.0)), None );
95        assert_eq!( not_foo.into_field(fp!(::Foo.1)), None );
96
97        assert_eq!( not_foo.is_variant(fp!(Foo)), false );
98    }
99}
100
101first_2( Enum::Foo(101,202), Enum::Bar );
102first_2( OtherEnum::Foo(101,202,"303"), OtherEnum::Bar );
103
104#[derive(Structural,Copy,Clone)]
105# #[struc(no_trait)]
106enum Enum{
107    Foo(u8,u8),
108    Bar,
109}
110
111#[derive(Structural,Copy,Clone)]
112# #[struc(no_trait)]
113enum OtherEnum{
114    Foo(u8,u8,&'static str),
115    Bar,
116}
117
118```
119
120
121
122
123
124*/
125
126
127#![allow(non_camel_case_types)]
128
129use crate::{
130    field::{IntoField, IntoFieldMut, IntoVariantFieldMut},
131    path::array_paths::{
132        I0, I1, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I2, I20, I21, I22, I23, I24, I25,
133        I26, I27, I28, I29, I3, I30, I31, I4, I5, I6, I7, I8, I9,
134    },
135};
136
137/*
138
139
140fn main() {
141    use std::fmt::Write;
142
143    const S:&'static str="    ";
144
145    let mut reg=String::new();
146
147    const MAX:usize=32;
148    const CHUNK_SIZE:usize=8;
149    const CHUNK_COUNT:usize=MAX/CHUNK_SIZE;
150
151    println!("declare_array_traits!{{");
152    for i in 0..CHUNK_COUNT {
153        let prev=i.saturating_sub(1)*8;
154        let curr=i*8;
155        let next=(i+1)*8;
156        let next=if next==MAX { MAX+1 }else{ next };
157
158        if next<MAX {
159            print!("{S}(Array_{0}_{1} [",curr,next,S=S);
160            if i!=0 {
161                print!("Array_{}_{} ",prev,curr);
162            }
163            print!("] [");
164            for field in curr..next {
165                print!("I{0} ",field);
166            }
167            println!("] )");
168        }
169        for arr_len in curr..next {
170            let _=write!(reg,"{S}(Array{0} [",arr_len,S=S);
171            if i!=0 {
172                let _=write!(reg,"Array_{}_{} ",prev,curr);
173            }
174            let _=write!(reg,"] [");
175            for field in curr..arr_len {
176                let _=write!(reg,"I{0} ",field);
177            }
178            let _=writeln!(reg,"] )");
179        }
180    }
181    println!("{}",reg);
182    println!("}}");
183}
184
185
186
187*/
188
189macro_rules! declare_array_traits {
190    (
191        $((
192            $(#[$meta:meta])*
193            $trait_name:ident
194            $trait_name_move:ident
195            [$($super_trait:ident)*]
196            [$($super_trait_move:ident)*]
197            [$($field:ident)*]
198        ))*
199    ) => (
200        $(
201            /// A structural alias for an array of this size.
202            /// With shared,mutable,and by value access to the elements.
203            $(#[$meta])*
204            pub trait $trait_name<T>:
205                $($super_trait<T>+)*
206                $(IntoFieldMut<$field,Ty=T> +)*
207            {}
208
209            impl<This,T>  $trait_name<T> for This
210            where
211                This:
212                    ?Sized+
213                    $($super_trait<T>+)*
214                    $(IntoFieldMut<$field,Ty=T> +)*
215            {}
216
217            /// A structural alias for an array of this size.
218            /// With shared and by value access to the elements.
219            $(#[$meta])*
220            pub trait $trait_name_move<T>:
221                $($super_trait_move<T>+)*
222                $(IntoField<$field,Ty=T> +)*
223            {}
224
225            impl<This,T>  $trait_name_move<T> for This
226            where
227                This:
228                    ?Sized+
229                    $($super_trait_move<T>+)*
230                    $(IntoField<$field,Ty=T> +)*
231            {}
232        )*
233    )
234}
235
236declare_array_traits! {
237    (
238        #[doc(hidden)]
239        Array_0_8 ArrayMove_0_8
240        [] []
241        [I0 I1 I2 I3 I4 I5 I6 I7 ]
242    )
243    (
244        #[doc(hidden)]
245        Array_8_16 ArrayMove_8_16
246        [Array_0_8] [ArrayMove_0_8]
247        [I8 I9 I10 I11 I12 I13 I14 I15 ]
248    )
249    (
250        #[doc(hidden)]
251        Array_16_24 ArrayMove_16_24
252        [Array_8_16] [ArrayMove_8_16]
253        [I16 I17 I18 I19 I20 I21 I22 I23 ]
254    )
255    (Array0  ArrayMove0  [] [] [] )
256    (Array1  ArrayMove1  [] [] [I0 ] )
257    (Array2  ArrayMove2  [] [] [I0 I1 ] )
258    (Array3  ArrayMove3  [] [] [I0 I1 I2 ] )
259    (Array4  ArrayMove4  [] [] [I0 I1 I2 I3 ] )
260    (Array5  ArrayMove5  [] [] [I0 I1 I2 I3 I4 ] )
261    (Array6  ArrayMove6  [] [] [I0 I1 I2 I3 I4 I5 ] )
262    (Array7  ArrayMove7  [] [] [I0 I1 I2 I3 I4 I5 I6 ] )
263    (Array8  ArrayMove8  [Array_0_8] [ArrayMove_0_8 ] [] )
264    (Array9  ArrayMove9  [Array_0_8] [ArrayMove_0_8 ] [I8 ] )
265    (Array10 ArrayMove10 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 ] )
266    (Array11 ArrayMove11 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 I10 ] )
267    (Array12 ArrayMove12 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 I10 I11 ] )
268    (Array13 ArrayMove13 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 I10 I11 I12 ] )
269    (Array14 ArrayMove14 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 I10 I11 I12 I13 ] )
270    (Array15 ArrayMove15 [Array_0_8] [ArrayMove_0_8 ] [I8 I9 I10 I11 I12 I13 I14 ] )
271    (Array16 ArrayMove16 [Array_8_16] [ArrayMove_8_16 ] [] )
272    (Array17 ArrayMove17 [Array_8_16] [ArrayMove_8_16 ] [I16 ] )
273    (Array18 ArrayMove18 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 ] )
274    (Array19 ArrayMove19 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 I18 ] )
275    (Array20 ArrayMove20 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 I18 I19 ] )
276    (Array21 ArrayMove21 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 I18 I19 I20 ] )
277    (Array22 ArrayMove22 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 I18 I19 I20 I21 ] )
278    (Array23 ArrayMove23 [Array_8_16] [ArrayMove_8_16 ] [I16 I17 I18 I19 I20 I21 I22 ] )
279    (Array24 ArrayMove24 [Array_16_24] [ArrayMove_16_24 ] [] )
280    (Array25 ArrayMove25 [Array_16_24] [ArrayMove_16_24 ] [I24 ] )
281    (Array26 ArrayMove26 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 ] )
282    (Array27 ArrayMove27 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 ] )
283    (Array28 ArrayMove28 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 I27 ] )
284    (Array29 ArrayMove29 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 I27 I28 ] )
285    (Array30 ArrayMove30 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 I27 I28 I29 ] )
286    (Array31 ArrayMove31 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 I27 I28 I29 I30 ] )
287    (Array32 ArrayMove32 [Array_16_24] [ArrayMove_16_24 ] [I24 I25 I26 I27 I28 I29 I30 I31 ] )
288
289}
290
291macro_rules! declare_array_traits {
292    (
293        $((
294            $(#[$meta:meta])*
295            $variant_trait_name:ident
296            [$($super_trait:ident)*]
297            [$($field:ident)*]
298        ))*
299    ) => (
300        $(
301            /// A structural alias for a tuple variant that's homogeneous
302            /// up to the size of the array).
303            ///
304            /// The `V` generic parameter is the name of the variant.
305            /// Examples of the `V` parameter for a variant named `Foo`:
306            /// - `TS!(Foo)`<br>
307            /// - `TS!(Bar)`<br>
308            /// - `TS!(0)`<br>
309            $(#[$meta])*
310            pub trait $variant_trait_name<T,V>:
311                $($super_trait<T,V>+)*
312                $(IntoVariantFieldMut<V,$field,Ty=T> +)*
313            {}
314
315            impl<This,V,T>  $variant_trait_name<T,V> for This
316            where
317                This:
318                    ?Sized+
319                    $($super_trait<T,V>+)*
320                    $(IntoVariantFieldMut<V,$field,Ty=T> +)*
321            {}
322        )*
323    )
324}
325
326declare_array_traits! {
327    (#[doc(hidden)] ArrayVariant_0_8 [] [I0 I1 I2 I3 I4 I5 I6 I7 ] )
328    (#[doc(hidden)] ArrayVariant_8_16 [ArrayVariant_0_8 ] [I8 I9 I10 I11 I12 I13 I14 I15 ] )
329    (#[doc(hidden)] ArrayVariant_16_24 [ArrayVariant_8_16 ] [I16 I17 I18 I19 I20 I21 I22 I23 ] )
330    (Array0Variant [] [] )
331    (Array1Variant [] [I0 ] )
332    (Array2Variant [] [I0 I1 ] )
333    (Array3Variant [] [I0 I1 I2 ] )
334    (Array4Variant [] [I0 I1 I2 I3 ] )
335    (Array5Variant [] [I0 I1 I2 I3 I4 ] )
336    (Array6Variant [] [I0 I1 I2 I3 I4 I5 ] )
337    (Array7Variant [] [I0 I1 I2 I3 I4 I5 I6 ] )
338    (Array8Variant [ArrayVariant_0_8 ] [] )
339    (Array9Variant [ArrayVariant_0_8 ] [I8 ] )
340    (Array10Variant [ArrayVariant_0_8 ] [I8 I9 ] )
341    (Array11Variant [ArrayVariant_0_8 ] [I8 I9 I10 ] )
342    (Array12Variant [ArrayVariant_0_8 ] [I8 I9 I10 I11 ] )
343    (Array13Variant [ArrayVariant_0_8 ] [I8 I9 I10 I11 I12 ] )
344    (Array14Variant [ArrayVariant_0_8 ] [I8 I9 I10 I11 I12 I13 ] )
345    (Array15Variant [ArrayVariant_0_8 ] [I8 I9 I10 I11 I12 I13 I14 ] )
346    (Array16Variant [ArrayVariant_8_16 ] [] )
347    (Array17Variant [ArrayVariant_8_16 ] [I16 ] )
348    (Array18Variant [ArrayVariant_8_16 ] [I16 I17 ] )
349    (Array19Variant [ArrayVariant_8_16 ] [I16 I17 I18 ] )
350    (Array20Variant [ArrayVariant_8_16 ] [I16 I17 I18 I19 ] )
351    (Array21Variant [ArrayVariant_8_16 ] [I16 I17 I18 I19 I20 ] )
352    (Array22Variant [ArrayVariant_8_16 ] [I16 I17 I18 I19 I20 I21 ] )
353    (Array23Variant [ArrayVariant_8_16 ] [I16 I17 I18 I19 I20 I21 I22 ] )
354    (Array24Variant [ArrayVariant_16_24 ] [] )
355    (Array25Variant [ArrayVariant_16_24 ] [I24 ] )
356    (Array26Variant [ArrayVariant_16_24 ] [I24 I25 ] )
357    (Array27Variant [ArrayVariant_16_24 ] [I24 I25 I26 ] )
358    (Array28Variant [ArrayVariant_16_24 ] [I24 I25 I26 I27 ] )
359    (Array29Variant [ArrayVariant_16_24 ] [I24 I25 I26 I27 I28 ] )
360    (Array30Variant [ArrayVariant_16_24 ] [I24 I25 I26 I27 I28 I29 ] )
361    (Array31Variant [ArrayVariant_16_24 ] [I24 I25 I26 I27 I28 I29 I30 ] )
362    (Array32Variant [ArrayVariant_16_24 ] [I24 I25 I26 I27 I28 I29 I30 I31 ] )
363}
364
365#[cfg(test)]
366#[allow(clippy::redundant_clone)]
367mod tests {
368    use super::{Array32, Array32Variant};
369    use crate::{Structural, StructuralExt, TS};
370
371    fn with_array_32<A>(mut this: A)
372    where
373        A: Array32<u32> + Clone,
374    {
375        assert_eq!(
376            this.fields(fp!(0, 1, 10, 11, 20, 21, 30, 31)),
377            (&0, &10, &100, &110, &200, &210, &300, &310),
378        );
379        assert_eq!(
380            this.fields_mut(fp!(0, 1, 10, 11, 20, 21, 30, 31)),
381            (&mut 0, &mut 10, &mut 100, &mut 110, &mut 200, &mut 210, &mut 300, &mut 310),
382        );
383        assert_eq!(this.clone().into_field(fp!(0)), 0);
384        assert_eq!(this.clone().into_field(fp!(1)), 10);
385        assert_eq!(this.clone().into_field(fp!(10)), 100);
386        assert_eq!(this.clone().into_field(fp!(11)), 110);
387        assert_eq!(this.clone().into_field(fp!(20)), 200);
388        assert_eq!(this.clone().into_field(fp!(21)), 210);
389        assert_eq!(this.clone().into_field(fp!(30)), 300);
390        assert_eq!(this.clone().into_field(fp!(31)), 310);
391    }
392    fn with_array_32_variant<A>(this: A)
393    where
394        A: Array32Variant<u32, TS!(Foo)> + Clone,
395    {
396        with_array_32(this.into_field(fp!(::Foo)).unwrap());
397    }
398
399    #[test]
400    fn array_32_test() {
401        let mut arr = [0u32; 32];
402        for i in 0..32u32 {
403            arr[i as usize] = i * 10;
404        }
405
406        with_array_32(arr);
407        with_array_32_variant(Enum::Foo(arr));
408    }
409
410    #[derive(Structural, Clone)]
411    enum Enum {
412        #[struc(newtype)]
413        Foo([u32; 32]),
414    }
415}