1use std::fmt;
61use std::mem;
62use std::slice;
63
64use std::error::Error as StdError;
65
66#[derive(Debug, PartialEq, Eq)]
68pub enum Error {
69 WrongAlignment,
73 IncompleteNumberOfValues,
76}
77
78impl fmt::Display for Error {
79 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
80 f.write_str(self.description())
81 }
82}
83
84impl StdError for Error {
85 fn description(&self) -> &str {
86 use self::Error::*;
87
88 match *self {
89 WrongAlignment => "Wrong Alignment",
90 IncompleteNumberOfValues => "Incomplete Number of Values",
91 }
92 }
93}
94
95fn check_constraints<T, U>(data: &[T]) -> Result<usize, Error> {
96 let alignment = mem::align_of::<U>();
97
98 if (data.as_ptr() as usize) % alignment != 0 {
99 return Err(Error::WrongAlignment);
100 }
101
102 let size_in = mem::size_of::<T>();
103 let size_out = mem::size_of::<U>();
104 if (data.len() * size_in) % size_out != 0 {
105 return Err(Error::IncompleteNumberOfValues);
106 }
107
108 Ok((data.len() * size_in) / size_out)
109}
110
111pub unsafe trait FromByteSlice
132where
133 Self: Sized,
134{
135 fn from_byte_slice<T: AsRef<[u8]> + ?Sized>(&T) -> Result<&[Self], Error>;
138 fn from_mut_byte_slice<T: AsMut<[u8]> + ?Sized>(&mut T) -> Result<&mut [Self], Error>;
141}
142
143pub unsafe trait ToByteSlice
165where
166 Self: Sized,
167{
168 fn to_byte_slice<T: AsRef<[Self]> + ?Sized>(slice: &T) -> Result<&[u8], Error>;
171}
172
173pub unsafe trait ToMutByteSlice
195where
196 Self: Sized,
197{
198 fn to_mut_byte_slice<T: AsMut<[Self]> + ?Sized>(slice: &mut T) -> Result<&mut [u8], Error>;
201}
202
203macro_rules! impl_trait(
204 ($to:ty) => {
205 unsafe impl FromByteSlice for $to {
206 fn from_byte_slice<T: AsRef<[u8]> + ?Sized>(slice: &T) -> Result<&[$to], Error> {
207 let slice = slice.as_ref();
208 let len = check_constraints::<u8, $to>(slice)?;
209 unsafe {
210 Ok(slice::from_raw_parts(slice.as_ptr() as *const $to, len))
211 }
212 }
213
214 fn from_mut_byte_slice<T: AsMut<[u8]> + ?Sized>(slice: &mut T) -> Result<&mut [$to], Error> {
215 let slice = slice.as_mut();
216 let len = check_constraints::<u8, $to>(slice)?;
217 unsafe {
218 Ok(slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut $to, len))
219 }
220 }
221 }
222
223 unsafe impl ToByteSlice for $to {
224 fn to_byte_slice<T: AsRef<[$to]> + ?Sized>(slice: &T) -> Result<&[u8], Error> {
225 let slice = slice.as_ref();
226 let len = check_constraints::<$to, u8>(slice)?;
227 unsafe {
228 Ok(slice::from_raw_parts(slice.as_ptr() as *const u8, len))
229 }
230 }
231 }
232
233 unsafe impl ToMutByteSlice for $to {
234 fn to_mut_byte_slice<T: AsMut<[$to]> + ?Sized>(slice: &mut T) -> Result<&mut [u8], Error> {
235 let slice = slice.as_mut();
236 let len = check_constraints::<$to, u8>(slice)?;
237 unsafe {
238 Ok(slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, len))
239 }
240 }
241 }
242 };
243);
244
245impl_trait!(u8);
246impl_trait!(u16);
247impl_trait!(u32);
248impl_trait!(u64);
249impl_trait!(u128);
250impl_trait!(i8);
251impl_trait!(i16);
252impl_trait!(i32);
253impl_trait!(i64);
254impl_trait!(i128);
255impl_trait!(f32);
256impl_trait!(f64);
257
258pub trait AsSliceOf {
279 fn as_slice_of<T: FromByteSlice>(&self) -> Result<&[T], Error>;
280}
281
282impl<U: AsRef<[u8]> + ?Sized> AsSliceOf for U {
283 fn as_slice_of<T: FromByteSlice>(&self) -> Result<&[T], Error> {
284 FromByteSlice::from_byte_slice(self)
285 }
286}
287
288pub trait AsMutSliceOf {
310 fn as_mut_slice_of<T: FromByteSlice>(&mut self) -> Result<&mut [T], Error>;
311}
312
313impl<U: AsMut<[u8]> + ?Sized> AsMutSliceOf for U {
314 fn as_mut_slice_of<T: FromByteSlice>(&mut self) -> Result<&mut [T], Error> {
315 FromByteSlice::from_mut_byte_slice(self)
316 }
317}
318
319pub trait AsByteSlice<T> {
341 fn as_byte_slice(&self) -> Result<&[u8], Error>;
342}
343
344impl<T: ToByteSlice, U: AsRef<[T]> + ?Sized> AsByteSlice<T> for U {
345 fn as_byte_slice(&self) -> Result<&[u8], Error> {
346 ToByteSlice::to_byte_slice(self)
347 }
348}
349
350pub trait AsMutByteSlice<T> {
370 fn as_mut_byte_slice(&mut self) -> Result<&mut [u8], Error>;
371}
372
373impl<T: ToMutByteSlice, U: AsMut<[T]> + ?Sized> AsMutByteSlice<T> for U {
374 fn as_mut_byte_slice(&mut self) -> Result<&mut [u8], Error> {
375 ToMutByteSlice::to_mut_byte_slice(self)
376 }
377}
378
379#[cfg(test)]
380mod tests {
381 use super::*;
382
383 #[test]
384 fn u8() {
385 let input: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
386
387 let output: &[u8] = input.as_slice_of::<u8>().unwrap();
388 assert_eq!(&input, output);
389
390 let output2: &[u8] = input.as_byte_slice().unwrap();
391 assert_eq!(&input, output2);
392 }
393
394 #[test]
395 fn u16() {
396 let slice: [u16; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
397 let bytes = slice.as_byte_slice().unwrap();
398
399 if cfg!(target_endian = "big") {
400 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
401 } else {
402 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
403 }
404
405 assert_eq!(
406 (&bytes[1..]).as_slice_of::<u16>(),
407 Err(Error::WrongAlignment)
408 );
409 assert_eq!(
410 (&bytes[0..15]).as_slice_of::<u16>(),
411 Err(Error::IncompleteNumberOfValues)
412 );
413 assert_eq!(bytes.as_slice_of::<u16>(), Ok(slice.as_ref()));
414 }
415
416 #[test]
417 fn u32() {
418 let slice: [u32; 4] = [0, 1, 2, 3];
419 let bytes = slice.as_byte_slice().unwrap();
420
421 if cfg!(target_endian = "big") {
422 assert_eq!(bytes, &[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3]);
423 } else {
424 assert_eq!(bytes, &[0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]);
425 }
426
427 assert_eq!(
428 (&bytes[1..]).as_slice_of::<u32>(),
429 Err(Error::WrongAlignment)
430 );
431 assert_eq!(
432 (&bytes[0..15]).as_slice_of::<u32>(),
433 Err(Error::IncompleteNumberOfValues)
434 );
435 assert_eq!(bytes.as_slice_of::<u32>(), Ok(slice.as_ref()));
436 }
437
438 #[test]
439 fn u64() {
440 let slice: [u64; 2] = [0, 1];
441 let bytes = slice.as_byte_slice().unwrap();
442
443 if cfg!(target_endian = "big") {
444 assert_eq!(bytes, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
445 } else {
446 assert_eq!(bytes, &[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
447 }
448
449 assert_eq!(
450 (&bytes[1..]).as_slice_of::<u64>(),
451 Err(Error::WrongAlignment)
452 );
453 assert_eq!(
454 (&bytes[0..15]).as_slice_of::<u64>(),
455 Err(Error::IncompleteNumberOfValues)
456 );
457 assert_eq!(bytes.as_slice_of::<u64>(), Ok(slice.as_ref()));
458 }
459
460 #[test]
461 fn f32() {
462 let slice: [f32; 4] = [2.0, 1.0, 0.5, 0.25];
463 let bytes = slice.as_byte_slice().unwrap();
464
465 if cfg!(target_endian = "big") {
466 assert_eq!(
467 bytes,
468 [
469 0x40, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3e,
470 0x80, 0x00, 0x00
471 ]
472 );
473 } else {
474 assert_eq!(
475 bytes,
476 [
477 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00,
478 0x00, 0x80, 0x3e
479 ]
480 );
481 };
482
483 assert_eq!(
484 (&bytes[1..]).as_slice_of::<f32>(),
485 Err(Error::WrongAlignment)
486 );
487 assert_eq!(
488 (&bytes[0..15]).as_slice_of::<f32>(),
489 Err(Error::IncompleteNumberOfValues)
490 );
491 assert_eq!(bytes.as_slice_of::<f32>(), Ok(slice.as_ref()));
492 }
493
494 #[test]
495 fn f64() {
496 let slice: [f64; 2] = [2.0, 0.5];
497 let bytes = slice.as_byte_slice().unwrap();
498
499 if cfg!(target_endian = "big") {
500 assert_eq!(
501 bytes,
502 [
503 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00
505 ]
506 );
507 } else {
508 assert_eq!(
509 bytes,
510 [
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x00, 0xe0, 0x3f
513 ]
514 );
515 };
516
517 assert_eq!(
518 (&bytes[1..]).as_slice_of::<f64>(),
519 Err(Error::WrongAlignment)
520 );
521 assert_eq!(
522 (&bytes[0..15]).as_slice_of::<f64>(),
523 Err(Error::IncompleteNumberOfValues)
524 );
525 assert_eq!(bytes.as_slice_of::<f64>(), Ok(slice.as_ref()));
526 }
527
528 #[test]
529 fn u16_mut() {
530 let mut slice: [u16; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
531 let mut slice_2: [u16; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
532 let bytes = slice_2.as_mut_byte_slice().unwrap();
533
534 if cfg!(target_endian = "big") {
535 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
536 } else {
537 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
538 }
539
540 assert_eq!(
541 (&mut bytes[1..]).as_mut_slice_of::<u16>(),
542 Err(Error::WrongAlignment)
543 );
544 assert_eq!(
545 (&mut bytes[0..15]).as_mut_slice_of::<u16>(),
546 Err(Error::IncompleteNumberOfValues)
547 );
548 assert_eq!(bytes.as_mut_slice_of::<u16>(), Ok(slice.as_mut()));
549 }
550
551 #[test]
552 fn u16_vec() {
553 let vec: Vec<u16> = vec![0, 1, 2, 3, 4, 5, 6, 7];
554 let bytes = vec.as_byte_slice().unwrap();
555
556 if cfg!(target_endian = "big") {
557 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
558 } else {
559 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
560 }
561
562 assert_eq!(
563 (&bytes[1..]).as_slice_of::<u16>(),
564 Err(Error::WrongAlignment)
565 );
566 assert_eq!(
567 (&bytes[0..15]).as_slice_of::<u16>(),
568 Err(Error::IncompleteNumberOfValues)
569 );
570 assert_eq!(bytes.as_slice_of::<u16>(), Ok(vec.as_ref()));
571 }
572
573 #[test]
574 fn u16_mut_vec() {
575 let mut vec: Vec<u16> = vec![0, 1, 2, 3, 4, 5, 6, 7];
576 let mut vec_clone = vec.clone();
577 let bytes = vec_clone.as_mut_byte_slice().unwrap();
578
579 if cfg!(target_endian = "big") {
580 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
581 } else {
582 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
583 }
584
585 assert_eq!(
586 (&mut bytes[1..]).as_mut_slice_of::<u16>(),
587 Err(Error::WrongAlignment)
588 );
589 assert_eq!(
590 (&mut bytes[0..15]).as_mut_slice_of::<u16>(),
591 Err(Error::IncompleteNumberOfValues)
592 );
593 assert_eq!(bytes.as_mut_slice_of::<u16>(), Ok(vec.as_mut()));
594 }
595
596 #[test]
597 fn u16_box_slice() {
598 let vec: Box<[u16]> = vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice();
599 let bytes = vec.as_byte_slice().unwrap();
600
601 if cfg!(target_endian = "big") {
602 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
603 } else {
604 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
605 }
606
607 assert_eq!(
608 (&bytes[1..]).as_slice_of::<u16>(),
609 Err(Error::WrongAlignment)
610 );
611 assert_eq!(
612 (&bytes[0..15]).as_slice_of::<u16>(),
613 Err(Error::IncompleteNumberOfValues)
614 );
615 assert_eq!(bytes.as_slice_of::<u16>(), Ok(vec.as_ref()));
616 }
617
618 #[test]
619 fn u16_mut_box_slice() {
620 let mut vec: Box<[u16]> = vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice();
621 let mut vec_clone: Box<[u16]> = vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice();
622 let bytes = vec_clone.as_mut_byte_slice().unwrap();
623
624 if cfg!(target_endian = "big") {
625 assert_eq!(bytes, &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7]);
626 } else {
627 assert_eq!(bytes, &[0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0]);
628 }
629
630 assert_eq!(
631 (&mut bytes[1..]).as_mut_slice_of::<u16>(),
632 Err(Error::WrongAlignment)
633 );
634 assert_eq!(
635 (&mut bytes[0..15]).as_mut_slice_of::<u16>(),
636 Err(Error::IncompleteNumberOfValues)
637 );
638 assert_eq!(bytes.as_mut_slice_of::<u16>(), Ok(vec.as_mut()));
639 }
640}