1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use slice;
use crateCast;
use crateReslice;
///
/// Defines methods to convert a reference to a variable into a
/// transmuted reference to a slice of the specified type without
/// copying data.
///
/// The antonym of [`Enslice`] is [`Deslice`].
///
/// [`Deslice`]: ./trait.Deslice.html
///
/// # Example
///
/// In the example below, method `enslice` converts the original
/// reference to type `ElfIdHdr` into a transmuted reference to
/// slice `bytes2` without copying data.
///
/// ```
/// # fn main() { test(); }
/// # fn test() -> Option<()> {
/// use castflip::experimental::Enslice;
/// use castflip::Cast;
///
/// #[repr(C)]
/// #[derive(Cast)]
/// struct ElfIdHdr {
/// magic: [u8; 4], //00-03: Magic Number 0x7F "ELF"
/// class: u8, //04 : File Class
/// encoding: u8, //05 : Data Encoding
/// version: u8, //06 : Version (should be 1)
/// os_abi: u8, //07 : OS and ABI
/// abi_ver: u8, //08 : ABI Version
/// pad: [u8; 7], //09-0F: Padding (should be 0)
/// }
///
/// // Input data: ELF Identification (16 bytes)
/// let hdr1 = ElfIdHdr {
/// magic: *b"\x7FELF", // 7F 45 4C 46
/// class: 2,
/// encoding: 1,
/// version: 1,
/// os_abi: 0,
/// abi_ver: 0,
/// pad: [0_u8; 7],
/// };
///
/// unsafe {
/// // Convert the original reference to `hdr1` into `bytes2`.
/// // Both &`hdr1` and `bytes2` point to the same entity.
/// // Hence, `bytes2` is the same with `bytes1`.
/// let bytes2: &[u8] = hdr1.enslice()?;
///
/// // Check the result (bytes2)
/// assert_eq!(bytes2, &[0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01, 0x00,
/// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
/// }
/// # Some(())
/// # }
/// ```
///
/// Note: [ELF] is a common standard file format for executable files.
/// ELF Identification is the first 16 bytes of the ELF header.
///
/// [ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
///
/// # Description
///
/// All methods in trait `Enslice` convert a reference to a variable
/// into a transmuted reference to a slice of the specified type
/// without copying data.
///
/// The size of the original variable and the size of the transmuted
/// slice must be the same. And the address of the original variable
/// must satisfy the requirement of the alignment of the transmuted
/// slice. If these requirements are satisfied, resulting reference
/// is returned in `Some`(). Otherwise, None is returned.
///
/// # Safety
///
/// We do not understand clearly what kind of problems could occur
/// with this trait.
///
/// Because the Rust compiler would not recognize what is happening,
/// it may reorder instructions unexpectedly. When a transmuted
/// reference is created by this trait, it would be better not to use
/// the original reference until the transmuted reference is dropped,
/// expecially when the original reference is mutable.
///