@@ -2011,6 +2011,360 @@ pub unsafe trait TryFromBytes {
2011
2011
}
2012
2012
}
2013
2013
2014
+ /// Attempts to interpret the prefix of the given `source` as a `&Self` with
2015
+ /// a DST length equal to `count`.
2016
+ ///
2017
+ /// This method attempts to return a reference to the prefix of `source`
2018
+ /// interpreted as a `Self` with `count` trailing elements, and a reference
2019
+ /// to the remaining bytes. If the length of `source` is less than the size
2020
+ /// of `Self` with `count` elements, if `source` is not appropriately
2021
+ /// aligned, or if the prefix of `source` does not contain a valid instance
2022
+ /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
2023
+ /// you can [infallibly discard the alignment error][ConvertError::from].
2024
+ ///
2025
+ /// [self-unaligned]: Unaligned
2026
+ /// [slice-dst]: KnownLayout#dynamically-sized-types
2027
+ ///
2028
+ /// # Examples
2029
+ ///
2030
+ /// ```
2031
+ /// # #![allow(non_camel_case_types)] // For C0::xC0
2032
+ /// use zerocopy::TryFromBytes;
2033
+ /// # use zerocopy_derive::*;
2034
+ ///
2035
+ /// // The only valid value of this type is the byte `0xC0`
2036
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2037
+ /// #[repr(u8)]
2038
+ /// enum C0 { xC0 = 0xC0 }
2039
+ ///
2040
+ /// // The only valid value of this type is the bytes `0xC0C0`.
2041
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2042
+ /// #[repr(C)]
2043
+ /// struct C0C0(C0, C0);
2044
+ ///
2045
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2046
+ /// #[repr(C)]
2047
+ /// struct Packet {
2048
+ /// magic_number: C0C0,
2049
+ /// mug_size: u8,
2050
+ /// temperature: u8,
2051
+ /// marshmallows: [[u8; 2]],
2052
+ /// }
2053
+ ///
2054
+ /// let bytes = &[0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];
2055
+ ///
2056
+ /// let (packet, suffix) = Packet::try_ref_from_prefix_with_elems(bytes, 3).unwrap();
2057
+ ///
2058
+ /// assert_eq!(packet.mug_size, 240);
2059
+ /// assert_eq!(packet.temperature, 77);
2060
+ /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2061
+ /// assert_eq!(suffix, &[8u8][..]);
2062
+ ///
2063
+ /// // These bytes are not valid instance of `Packet`.
2064
+ /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2065
+ /// assert!(Packet::try_ref_from_prefix_with_elems(bytes, 3).is_err());
2066
+ /// ```
2067
+ ///
2068
+ /// Since an explicit `count` is provided, this method supports types with
2069
+ /// zero-sized trailing slice elements. Methods such as [`try_ref_from_prefix`]
2070
+ /// which do not take an explicit count do not support such types.
2071
+ ///
2072
+ /// ```
2073
+ /// use core::num::NonZeroU16;
2074
+ /// use zerocopy::*;
2075
+ /// # use zerocopy_derive::*;
2076
+ ///
2077
+ /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2078
+ /// #[repr(C)]
2079
+ /// struct ZSTy {
2080
+ /// leading_sized: NonZeroU16,
2081
+ /// trailing_dst: [()],
2082
+ /// }
2083
+ ///
2084
+ /// let src = &[85, 85][..];
2085
+ /// let (zsty, _) = ZSTy::try_ref_from_prefix_with_elems(src, 42).unwrap();
2086
+ /// assert_eq!(zsty.trailing_dst.len(), 42);
2087
+ /// ```
2088
+ ///
2089
+ /// [`try_ref_from_prefix`]: TryFromBytes::try_ref_from_prefix
2090
+ #[ must_use = "has no side effects" ]
2091
+ #[ inline]
2092
+ fn try_ref_from_prefix_with_elems (
2093
+ source : & [ u8 ] ,
2094
+ count : usize ,
2095
+ ) -> Result < ( & Self , & [ u8 ] ) , TryCastError < & [ u8 ] , Self > >
2096
+ where
2097
+ Self : KnownLayout < PointerMetadata = usize > + Immutable ,
2098
+ {
2099
+ try_ref_from_prefix_suffix ( source, CastType :: Prefix , Some ( count) )
2100
+ }
2101
+
2102
+ /// Attempts to interpret the suffix of the given `source` as a `&Self` with
2103
+ /// a DST length equal to `count`.
2104
+ ///
2105
+ /// This method attempts to return a reference to the suffix of `source`
2106
+ /// interpreted as a `Self` with `count` trailing elements, and a reference
2107
+ /// to the preceding bytes. If the length of `source` is less than the size
2108
+ /// of `Self` with `count` elements, if the suffix of `source` is not
2109
+ /// appropriately aligned, or if the suffix of `source` does not contain a
2110
+ /// valid instance of `Self`, this returns `Err`. If [`Self:
2111
+ /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
2112
+ /// error][ConvertError::from].
2113
+ ///
2114
+ /// [self-unaligned]: Unaligned
2115
+ /// [slice-dst]: KnownLayout#dynamically-sized-types
2116
+ ///
2117
+ /// # Examples
2118
+ ///
2119
+ /// ```
2120
+ /// # #![allow(non_camel_case_types)] // For C0::xC0
2121
+ /// use zerocopy::TryFromBytes;
2122
+ /// # use zerocopy_derive::*;
2123
+ ///
2124
+ /// // The only valid value of this type is the byte `0xC0`
2125
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2126
+ /// #[repr(u8)]
2127
+ /// enum C0 { xC0 = 0xC0 }
2128
+ ///
2129
+ /// // The only valid value of this type is the bytes `0xC0C0`.
2130
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2131
+ /// #[repr(C)]
2132
+ /// struct C0C0(C0, C0);
2133
+ ///
2134
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2135
+ /// #[repr(C)]
2136
+ /// struct Packet {
2137
+ /// magic_number: C0C0,
2138
+ /// mug_size: u8,
2139
+ /// temperature: u8,
2140
+ /// marshmallows: [[u8; 2]],
2141
+ /// }
2142
+ ///
2143
+ /// let bytes = &[123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2144
+ ///
2145
+ /// let (prefix, packet) = Packet::try_ref_from_suffix_with_elems(bytes, 3).unwrap();
2146
+ ///
2147
+ /// assert_eq!(packet.mug_size, 240);
2148
+ /// assert_eq!(packet.temperature, 77);
2149
+ /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2150
+ /// assert_eq!(prefix, &[123u8][..]);
2151
+ ///
2152
+ /// // These bytes are not valid instance of `Packet`.
2153
+ /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2154
+ /// assert!(Packet::try_ref_from_suffix_with_elems(bytes, 3).is_err());
2155
+ /// ```
2156
+ ///
2157
+ /// Since an explicit `count` is provided, this method supports types with
2158
+ /// zero-sized trailing slice elements. Methods such as [`try_ref_from_prefix`]
2159
+ /// which do not take an explicit count do not support such types.
2160
+ ///
2161
+ /// ```
2162
+ /// use core::num::NonZeroU16;
2163
+ /// use zerocopy::*;
2164
+ /// # use zerocopy_derive::*;
2165
+ ///
2166
+ /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2167
+ /// #[repr(C)]
2168
+ /// struct ZSTy {
2169
+ /// leading_sized: NonZeroU16,
2170
+ /// trailing_dst: [()],
2171
+ /// }
2172
+ ///
2173
+ /// let src = &[85, 85][..];
2174
+ /// let (_, zsty) = ZSTy::try_ref_from_suffix_with_elems(src, 42).unwrap();
2175
+ /// assert_eq!(zsty.trailing_dst.len(), 42);
2176
+ /// ```
2177
+ ///
2178
+ /// [`try_ref_from_prefix`]: TryFromBytes::try_ref_from_prefix
2179
+ #[ must_use = "has no side effects" ]
2180
+ #[ inline]
2181
+ fn try_ref_from_suffix_with_elems (
2182
+ source : & [ u8 ] ,
2183
+ count : usize ,
2184
+ ) -> Result < ( & [ u8 ] , & Self ) , TryCastError < & [ u8 ] , Self > >
2185
+ where
2186
+ Self : KnownLayout < PointerMetadata = usize > + Immutable ,
2187
+ {
2188
+ try_ref_from_prefix_suffix ( source, CastType :: Suffix , Some ( count) ) . map ( swap)
2189
+ }
2190
+
2191
+ /// Attempts to interpret the prefix of the given `source` as a `&Self` with
2192
+ /// a DST length equal to `count`.
2193
+ ///
2194
+ /// This method attempts to return a reference to the prefix of `source`
2195
+ /// interpreted as a `Self` with `count` trailing elements, and a reference
2196
+ /// to the remaining bytes. If the length of `source` is less than the size
2197
+ /// of `Self` with `count` elements, if `source` is not appropriately
2198
+ /// aligned, or if the prefix of `source` does not contain a valid instance
2199
+ /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
2200
+ /// you can [infallibly discard the alignment error][ConvertError::from].
2201
+ ///
2202
+ /// [self-unaligned]: Unaligned
2203
+ /// [slice-dst]: KnownLayout#dynamically-sized-types
2204
+ ///
2205
+ /// # Examples
2206
+ ///
2207
+ /// ```
2208
+ /// # #![allow(non_camel_case_types)] // For C0::xC0
2209
+ /// use zerocopy::TryFromBytes;
2210
+ /// # use zerocopy_derive::*;
2211
+ ///
2212
+ /// // The only valid value of this type is the byte `0xC0`
2213
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2214
+ /// #[repr(u8)]
2215
+ /// enum C0 { xC0 = 0xC0 }
2216
+ ///
2217
+ /// // The only valid value of this type is the bytes `0xC0C0`.
2218
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2219
+ /// #[repr(C)]
2220
+ /// struct C0C0(C0, C0);
2221
+ ///
2222
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2223
+ /// #[repr(C)]
2224
+ /// struct Packet {
2225
+ /// magic_number: C0C0,
2226
+ /// mug_size: u8,
2227
+ /// temperature: u8,
2228
+ /// marshmallows: [[u8; 2]],
2229
+ /// }
2230
+ ///
2231
+ /// let bytes = &mut [0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];
2232
+ ///
2233
+ /// let (packet, suffix) = Packet::try_mut_from_prefix_with_elems(bytes, 3).unwrap();
2234
+ ///
2235
+ /// assert_eq!(packet.mug_size, 240);
2236
+ /// assert_eq!(packet.temperature, 77);
2237
+ /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2238
+ /// assert_eq!(suffix, &[8u8][..]);
2239
+ ///
2240
+ /// // These bytes are not valid instance of `Packet`.
2241
+ /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2242
+ /// assert!(Packet::try_mut_from_prefix_with_elems(bytes, 3).is_err());
2243
+ /// ```
2244
+ ///
2245
+ /// Since an explicit `count` is provided, this method supports types with
2246
+ /// zero-sized trailing slice elements. Methods such as [`try_mut_from_prefix`]
2247
+ /// which do not take an explicit count do not support such types.
2248
+ ///
2249
+ /// ```
2250
+ /// use core::num::NonZeroU16;
2251
+ /// use zerocopy::*;
2252
+ /// # use zerocopy_derive::*;
2253
+ ///
2254
+ /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2255
+ /// #[repr(C)]
2256
+ /// struct ZSTy {
2257
+ /// leading_sized: NonZeroU16,
2258
+ /// trailing_dst: [()],
2259
+ /// }
2260
+ ///
2261
+ /// let src = &mut [85, 85][..];
2262
+ /// let (zsty, _) = ZSTy::try_mut_from_prefix_with_elems(src, 42).unwrap();
2263
+ /// assert_eq!(zsty.trailing_dst.len(), 42);
2264
+ /// ```
2265
+ ///
2266
+ /// [`try_mut_from_prefix`]: TryFromBytes::try_mut_from_prefix
2267
+ #[ must_use = "has no side effects" ]
2268
+ #[ inline]
2269
+ fn try_mut_from_prefix_with_elems (
2270
+ source : & mut [ u8 ] ,
2271
+ count : usize ,
2272
+ ) -> Result < ( & mut Self , & mut [ u8 ] ) , TryCastError < & mut [ u8 ] , Self > >
2273
+ where
2274
+ Self : KnownLayout < PointerMetadata = usize > + Immutable ,
2275
+ {
2276
+ try_mut_from_prefix_suffix ( source, CastType :: Prefix , Some ( count) )
2277
+ }
2278
+
2279
+ /// Attempts to interpret the suffix of the given `source` as a `&mut Self`
2280
+ /// with a DST length equal to `count`.
2281
+ ///
2282
+ /// This method attempts to return a reference to the suffix of `source`
2283
+ /// interpreted as a `Self` with `count` trailing elements, and a reference
2284
+ /// to the preceding bytes. If the length of `source` is less than the size
2285
+ /// of `Self` with `count` elements, if the suffix of `source` is not
2286
+ /// appropriately aligned, or if the suffix of `source` does not contain a
2287
+ /// valid instance of `Self`, this returns `Err`. If [`Self:
2288
+ /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
2289
+ /// error][ConvertError::from].
2290
+ ///
2291
+ /// [self-unaligned]: Unaligned
2292
+ /// [slice-dst]: KnownLayout#dynamically-sized-types
2293
+ ///
2294
+ /// # Examples
2295
+ ///
2296
+ /// ```
2297
+ /// # #![allow(non_camel_case_types)] // For C0::xC0
2298
+ /// use zerocopy::TryFromBytes;
2299
+ /// # use zerocopy_derive::*;
2300
+ ///
2301
+ /// // The only valid value of this type is the byte `0xC0`
2302
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2303
+ /// #[repr(u8)]
2304
+ /// enum C0 { xC0 = 0xC0 }
2305
+ ///
2306
+ /// // The only valid value of this type is the bytes `0xC0C0`.
2307
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2308
+ /// #[repr(C)]
2309
+ /// struct C0C0(C0, C0);
2310
+ ///
2311
+ /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2312
+ /// #[repr(C)]
2313
+ /// struct Packet {
2314
+ /// magic_number: C0C0,
2315
+ /// mug_size: u8,
2316
+ /// temperature: u8,
2317
+ /// marshmallows: [[u8; 2]],
2318
+ /// }
2319
+ ///
2320
+ /// let bytes = &mut [123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2321
+ ///
2322
+ /// let (prefix, packet) = Packet::try_mut_from_suffix_with_elems(bytes, 3).unwrap();
2323
+ ///
2324
+ /// assert_eq!(packet.mug_size, 240);
2325
+ /// assert_eq!(packet.temperature, 77);
2326
+ /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2327
+ /// assert_eq!(prefix, &[123u8][..]);
2328
+ ///
2329
+ /// // These bytes are not valid instance of `Packet`.
2330
+ /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2331
+ /// assert!(Packet::try_mut_from_suffix_with_elems(bytes, 3).is_err());
2332
+ /// ```
2333
+ ///
2334
+ /// Since an explicit `count` is provided, this method supports types with
2335
+ /// zero-sized trailing slice elements. Methods such as [`try_mut_from_prefix`]
2336
+ /// which do not take an explicit count do not support such types.
2337
+ ///
2338
+ /// ```
2339
+ /// use core::num::NonZeroU16;
2340
+ /// use zerocopy::*;
2341
+ /// # use zerocopy_derive::*;
2342
+ ///
2343
+ /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2344
+ /// #[repr(C)]
2345
+ /// struct ZSTy {
2346
+ /// leading_sized: NonZeroU16,
2347
+ /// trailing_dst: [()],
2348
+ /// }
2349
+ ///
2350
+ /// let src = &mut [85, 85][..];
2351
+ /// let (_, zsty) = ZSTy::try_mut_from_suffix_with_elems(src, 42).unwrap();
2352
+ /// assert_eq!(zsty.trailing_dst.len(), 42);
2353
+ /// ```
2354
+ ///
2355
+ /// [`try_mut_from_prefix`]: TryFromBytes::try_mut_from_prefix
2356
+ #[ must_use = "has no side effects" ]
2357
+ #[ inline]
2358
+ fn try_mut_from_suffix_with_elems (
2359
+ source : & mut [ u8 ] ,
2360
+ count : usize ,
2361
+ ) -> Result < ( & mut [ u8 ] , & mut Self ) , TryCastError < & mut [ u8 ] , Self > >
2362
+ where
2363
+ Self : KnownLayout < PointerMetadata = usize > + Immutable ,
2364
+ {
2365
+ try_mut_from_prefix_suffix ( source, CastType :: Suffix , Some ( count) ) . map ( swap)
2366
+ }
2367
+
2014
2368
/// Attempts to read the given `source` as a `Self`.
2015
2369
///
2016
2370
/// If `source.len() != size_of::<Self>()` or the bytes are not a valid
0 commit comments