binary_layout/fields/primitive/copy_access/
primitive_unit.rs

1use core::convert::Infallible;
2
3use super::{FieldCopyAccess, PrimitiveField};
4use crate::endianness::Endianness;
5use crate::fields::primitive::view::FieldView;
6use crate::fields::{Field, StorageIntoFieldView, StorageToFieldView};
7
8impl<E: Endianness, const OFFSET_: usize> FieldCopyAccess for PrimitiveField<(), E, OFFSET_> {
9    /// See [FieldCopyAccess::ReadError]
10    type ReadError = Infallible;
11    /// See [FieldCopyAccess::WriteError]
12    type WriteError = Infallible;
13    /// See [FieldCopyAccess::HighLevelType]
14    type HighLevelType = ();
15
16    doc_comment::doc_comment! {
17        concat! {"
18                'Read' the `", stringify!(()), "`-typed field from a given data region, assuming the defined layout, using the [Field] API.
19
20                # Example:
21
22                ```
23                use binary_layout::prelude::*;
24
25                binary_layout!(my_layout, LittleEndian, {
26                    //... other fields ...
27                    some_zst_field: ", stringify!(()), "
28                    //... other fields ...
29                });
30
31                fn func(storage_data: &[u8]) {
32                    let read: ", stringify!(()), " = my_layout::some_zst_field::try_read(storage_data).unwrap();
33                    read
34                }
35                ```
36
37                In reality, this method doesn't do any work; `",
38                stringify!(()), "` is a zero-sized type, so there's no work to
39                do. This implementation exists solely to make writing derive
40                macros simpler.
41                "},
42        #[inline(always)]
43        #[allow(clippy::unused_unit)] // I don't want to remove this as it's part of the trait.
44        fn try_read(_storage: &[u8]) -> Result<(), Infallible> {
45            Ok(())
46        }
47    }
48
49    doc_comment::doc_comment! {
50        concat! {"
51                'Write' the `", stringify!(()), "`-typed field to a given data region, assuming the defined layout, using the [Field] API.
52
53                # Example:
54
55                ```
56                use binary_layout::prelude::*;
57
58                binary_layout!(my_layout, LittleEndian, {
59                    //... other fields ...
60                    some_zst_field: ", stringify!(()), "
61                    //... other fields ...
62                });
63
64                fn func(storage_data: &mut [u8]) {
65                    my_layout::some_zst_field::try_write(storage_data, ()).unwrap();
66                }
67                ```
68
69                # WARNING
70
71                In reality, this method doesn't do any work; `",
72                stringify!(()), "` is a zero-sized type, so there's no work to
73                do. This implementation exists solely to make writing derive
74                macros simpler.
75                "},
76        #[inline(always)]
77        #[allow(clippy::unused_unit)] // I don't want to remove this as it's part of the trait.
78        fn try_write(_storage: &mut [u8], _value: ()) -> Result<(), Infallible> {
79            Ok(())
80        }
81    }
82}
83
84impl_field_traits!(());
85
86#[cfg(test)]
87mod tests {
88    use crate::prelude::*;
89    use crate::PrimitiveField;
90
91    macro_rules! test_unit_copy_access {
92        ($endian:ident, $endian_type:ty) => {
93            $crate::internal::paste! {
94                #[test]
95                fn [<test_unit_ $endian endian_metadata>]() {
96                    type Field1 = PrimitiveField<(), $endian_type, 5>;
97                    type Field2 = PrimitiveField<(), $endian_type, 123>;
98
99                    assert_eq!(Some(0), Field1::SIZE);
100                    assert_eq!(5, Field1::OFFSET);
101                    assert_eq!(Some(0), Field2::SIZE);
102                    assert_eq!(123, Field2::OFFSET);
103                }
104
105                #[allow(clippy::unit_cmp)]
106                #[test]
107                fn [<test_unit_ $endian endian_fieldapi>]() {
108                    let mut storage = [0; 1024];
109
110                    type Field1 = PrimitiveField<(), $endian_type, 5>;
111                    type Field2 = PrimitiveField<(), $endian_type, 123>;
112
113                    Field1::write(&mut storage, ());
114                    Field2::write(&mut storage, ());
115
116                    assert_eq!((), Field1::read(&storage));
117                    assert_eq!((), Field2::read(&storage));
118
119                    // Zero-sized types do not mutate the storage, so it should remain
120                    // unchanged for all of time.
121                    assert_eq!(storage, [0; 1024]);
122                }
123
124                #[allow(clippy::unit_cmp)]
125                #[test]
126                fn [<test_unit_ $endian endian_viewapi>]() {
127                    binary_layout!(layout, $endian_type, {
128                        field1: (),
129                        field2: (),
130                    });
131                    let mut storage = [0; 1024];
132                    let mut view = layout::View::new(&mut storage);
133
134                    view.field1_mut().write(());
135                    view.field2_mut().write(());
136
137                    assert_eq!((), view.field1().read());
138                    assert_eq!((), view.field2().read());
139
140                    // Zero-sized types do not mutate the storage, so it should remain
141                    // unchanged for all of time.
142                    assert_eq!(storage, [0; 1024]);
143                }
144            }
145        };
146    }
147
148    test_unit_copy_access!(little, LittleEndian);
149    test_unit_copy_access!(big, BigEndian);
150    test_unit_copy_access!(native, NativeEndian);
151}