Repository: sharksforarms/deku
Pull request #87 (2020-08-17 12:36:07)

fix: Update to latest bitvec
Fixes https://github.com/sharksforarms/deku/issues/85

codecov[bot]: # [Codecov](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=h1) Report
> Merging [#87](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=desc) into [master](https://codecov.io/gh/sharksforarms/deku/commit/bba07c5bc5af6703314173fb8e054e2380581766&el=desc) will **increase** coverage by `0.34%`.
> The diff coverage is `85.71%`.

[![Impacted file tree graph](https://codecov.io/gh/sharksforarms/deku/pull/87/graphs/tree.svg?width=650&height=150&src=pr&token=MFMETW02MZ)](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #87      +/-   ##
==========================================
+ Coverage   85.78%   86.13%   +0.34%     
==========================================
  Files           8        8              
  Lines         950      952       +2     
==========================================
+ Hits          815      820       +5     
+ Misses        135      132       -3     
```


| [Impacted Files](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [deku-derive/src/macros/deku\_read.rs](https://codecov.io/gh/sharksforarms/deku/pull/87/diff?src=pr&el=tree#diff-ZGVrdS1kZXJpdmUvc3JjL21hY3Jvcy9kZWt1X3JlYWQucnM=) | `98.18% <ø> (ø)` | |
| [src/error.rs](https://codecov.io/gh/sharksforarms/deku/pull/87/diff?src=pr&el=tree#diff-c3JjL2Vycm9yLnJz) | `18.75% <0.00%> (-1.25%)` | :arrow_down: |
| [src/lib.rs](https://codecov.io/gh/sharksforarms/deku/pull/87/diff?src=pr&el=tree#diff-c3JjL2xpYi5ycw==) | `94.90% <100.00%> (+1.59%)` | :arrow_up: |
| [src/slice\_impls.rs](https://codecov.io/gh/sharksforarms/deku/pull/87/diff?src=pr&el=tree#diff-c3JjL3NsaWNlX2ltcGxzLnJz) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=footer). Last update [bba07c5...f454388](https://codecov.io/gh/sharksforarms/deku/pull/87?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

github-actions[bot]: ## Benchmark for c235193
  <details>
    <summary>Click to view benchmark</summary>

| Test | PR Benchmark | Master Benchmark | % |
|------|--------------|------------------|---|
| deku_read_byte | **12.1±0.40ns** | 27.0±1.19ns | -23% |
| deku_read_enum | **21.7±1.06ns** | 47.5±0.54ns | -18.999999999999993% |
| deku_read_vec | **1107.7±46.32ns** | 1657.4±95.63ns | 50% |
| deku_write_byte | **101.8±4.44ns** | 157.1±1.03ns | 46% |
| deku_write_enum | **192.3±10.96ns** | 300.4±3.47ns | 43.99999999999999% |
| deku_write_vec | **11.9±0.53µs** | 21.9±1.04µs | 15.999999999999993% |

  </details>
  
github-actions[bot]: ## Benchmark for 091dd84
  <details>
    <summary>Click to view benchmark</summary>

| Test | PR Benchmark | Master Benchmark | % |
|------|--------------|------------------|---|
| deku_read_byte | **11.2±0.67ns** | 23.8±3.90ns | -12.99999999999999% |
| deku_read_enum | **20.5±1.01ns** | 37.4±2.53ns | 16.999999999999993% |
| deku_read_vec | **1010.6±60.01ns** | 1352.5±72.98ns | 65.99999999999999% |
| deku_write_byte | **88.8±4.34ns** | 132.7±7.80ns | 51% |
| deku_write_enum | **169.8±11.83ns** | 251.1±19.21ns | 52% |
| deku_write_vec | **10.6±0.71µs** | 20.2±1.72µs | 10.000000000000009% |

  </details>
  
github-actions[bot]: ## Benchmark for 7d71b0c
  <details>
    <summary>Click to view benchmark</summary>

| Test | PR Benchmark | Master Benchmark | % |
|------|--------------|------------------|---|
| deku_read_byte | **12.5±0.34ns** | 27.0±1.33ns | -16.000000000000014% |
| deku_read_enum | **23.0±1.08ns** | 42.9±2.10ns | 12.99999999999999% |
| deku_read_vec | **1170.0±70.68ns** | 1592.2±24.75ns | 63.99999999999999% |
| deku_write_byte | **107.8±4.91ns** | 152.3±8.21ns | 59.00000000000001% |
| deku_write_enum | **197.3±8.46ns** | 289.0±10.43ns | 53% |
| deku_write_vec | **13.8±0.66µs** | 23.1±0.65µs | 33.00000000000001% |

  </details>
  
github-actions[bot]: ## Benchmark for 4daca6d
  <details>
    <summary>Click to view benchmark</summary>

| Test | PR Benchmark | Master Benchmark | % |
|------|--------------|------------------|---|
| deku_read_byte | **11.8±0.97ns** | 24.6±2.16ns | -8.000000000000007% |
| deku_read_enum | **20.9±1.32ns** | 40.8±2.61ns | 4.0000000000000036% |
| deku_read_vec | **1020.5±82.02ns** | 1497.1±93.10ns | 53% |
| deku_write_byte | **89.6±6.63ns** | 150.8±8.35ns | 32.00000000000001% |
| deku_write_enum | **176.1±13.51ns** | 292.9±19.18ns | 34.00000000000001% |
| deku_write_vec | **10.9±0.66µs** | 23.2±2.15µs | -12.99999999999999% |

  </details>
  
github-actions[bot]: ## Benchmark for 6140aaa
  <details>
    <summary>Click to view benchmark</summary>

| Test | PR Benchmark | Master Benchmark | % |
|------|--------------|------------------|---|
| deku_read_byte | **12.5±0.19ns** | 27.4±0.40ns | -20.000000000000018% |
| deku_read_enum | **22.6±0.34ns** | 45.2±1.22ns | 0% |
| deku_read_vec | **1062.5±21.67ns** | 1678.9±36.57ns | 41.99999999999999% |
| deku_write_byte | 188.8±6.31ns | **154.5±4.24ns** | 122% |
| deku_write_enum | 358.7±4.69ns | **291.6±8.56ns** | 123% |
| deku_write_vec | 28.2±0.64µs | **23.6±0.52µs** | 120% |

  </details>
  

Patch:
diff --git a/Cargo.toml b/Cargo.toml
index b1a0342..3a8ca0b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,7 +25,7 @@ alloc = ["bitvec/alloc"]
 
 [dependencies]
 deku_derive = { version = "^0.7.0", path = "deku-derive" }
-bitvec = { version = "0.17", default-features = false }
+bitvec = { version = "0.18", default-features = false }
 
 [dev-dependencies]
 hex-literal = "0.3"
diff --git a/deku-derive/src/macros/deku_read.rs b/deku-derive/src/macros/deku_read.rs
index 1a73112..fbf07db 100644
--- a/deku-derive/src/macros/deku_read.rs
+++ b/deku-derive/src/macros/deku_read.rs
@@ -56,9 +56,9 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
         impl #imp DekuContainerRead for #ident #wher {
             fn from_bytes(input: (&[u8], usize)) -> Result<((&[u8], usize), Self), DekuError> {
                 use core::convert::TryFrom;
-                let input_bits = input.0.bits::<Msb0>();
+                let input_bits = input.0.view_bits::<Msb0>();
 
-                let mut rest = input.0.bits::<Msb0>();
+                let mut rest = input.0.view_bits::<Msb0>();
                 rest = &rest[input.1..];
 
                 #(#field_reads)*
@@ -220,9 +220,9 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
         impl #imp DekuContainerRead for #ident #wher {
             fn from_bytes(input: (&[u8], usize)) -> Result<((&[u8], usize), Self), DekuError> {
                 use core::convert::TryFrom;
-                let input_bits = input.0.bits::<Msb0>();
+                let input_bits = input.0.view_bits::<Msb0>();
 
-                let mut rest = input.0.bits::<Msb0>();
+                let mut rest = input.0.view_bits::<Msb0>();
                 rest = &rest[input.1..];
 
                 #variant_read
diff --git a/ensure_no_std/src/bin/main.rs b/ensure_no_std/src/bin/main.rs
index 847eea8..3783e8d 100644
--- a/ensure_no_std/src/bin/main.rs
+++ b/ensure_no_std/src/bin/main.rs
@@ -16,7 +16,7 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
 // raise a `trap` the WebAssembly execution if we panic at runtime.
 #[panic_handler]
 #[no_mangle]
-pub fn panic(_info: &::core::panic::PanicInfo) -> ! {
+unsafe fn panic(_info: &::core::panic::PanicInfo) -> ! {
     ::core::intrinsics::abort();
 }
 
@@ -24,14 +24,14 @@ pub fn panic(_info: &::core::panic::PanicInfo) -> ! {
 // the execution with trap.
 #[alloc_error_handler]
 #[no_mangle]
-pub extern "C" fn oom(_: ::core::alloc::Layout) -> ! {
+unsafe fn oom(_: ::core::alloc::Layout) -> ! {
     ::core::intrinsics::abort();
 }
 
 // Needed for non-wasm targets.
 #[lang = "eh_personality"]
 #[no_mangle]
-pub extern "C" fn eh_personality() {}
+extern fn eh_personality() {}
 
 use alloc::{format, vec, vec::Vec};
 use deku::prelude::*;
diff --git a/src/error.rs b/src/error.rs
index 4d99151..4fd970b 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -8,6 +8,8 @@ pub enum DekuError {
     Parse(String),
     /// Invalid parameter
     InvalidParam(String),
+    /// Unexpected error
+    Unexpected(String),
 }
 
 impl From<core::num::TryFromIntError> for DekuError {
@@ -33,6 +35,7 @@ impl core::fmt::Display for DekuError {
         match *self {
             DekuError::Parse(ref err) => write!(f, "Parse error: {}", err),
             DekuError::InvalidParam(ref err) => write!(f, "Invalid param error: {}", err),
+            DekuError::Unexpected(ref err) => write!(f, "Unexpected error: {}", err),
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 6205ef6..24c280d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -209,7 +209,7 @@ assert_eq!(value.sub.b, 0x01 + 0x02)
 extern crate alloc;
 
 #[cfg(feature = "alloc")]
-use alloc::{format, vec::Vec};
+use alloc::{format, string::ToString, vec::Vec};
 
 #[cfg(feature = "std")]
 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
@@ -416,7 +416,10 @@ macro_rules! ImplDekuTraits {
 
                 let bit_size: usize = bit_size.into();
 
-                let input_bits: BitVec<Msb0, u8> = input.to_vec().into();
+                let input_bits: BitVec<Msb0, u8> = input
+                    .to_vec()
+                    .try_into()
+                    .map_err(|_e| DekuError::Unexpected("Converting Vec to BitVec".to_string()))?;
 
                 let res_bits: BitVec<Msb0, u8> = {
                     if bit_size > input_bits.len() {
@@ -472,7 +475,10 @@ macro_rules! ImplDekuTraits {
                     self.to_be_bytes()
                 };
 
-                Ok(input.to_vec().into())
+                Ok(input
+                    .to_vec()
+                    .try_into()
+                    .map_err(|_e| DekuError::Unexpected("Converting Vec to BitVec".to_string()))?)
             }
         }
 
@@ -499,9 +505,9 @@ impl<T: DekuRead<Ctx>, Ctx: Copy> DekuRead<(Count, Ctx)> for Vec<T> {
     /// ```rust
     /// # use deku::ctx::*;
     /// # use deku::DekuRead;
-    /// # use bitvec::slice::AsBits;
+    /// # use bitvec::view::BitView;
     /// let input = vec![1u8, 2, 3, 4];
-    /// let (rest, v) = Vec::<u32>::read(input.bits(), (1.into(), Endian::Little)).unwrap();
+    /// let (rest, v) = Vec::<u32>::read(input.view_bits(), (1.into(), Endian::Little)).unwrap();
     /// assert!(rest.is_empty());
     /// assert_eq!(v, vec![0x04030201])
     /// ```
@@ -569,9 +575,9 @@ impl<T: DekuRead<Ctx>, Ctx: Copy> DekuRead<Ctx> for Option<T> {
     /// ```rust
     /// # use deku::ctx::*;
     /// # use deku::DekuRead;
-    /// # use bitvec::slice::AsBits;
+    /// # use bitvec::view::BitView;
     /// let input = vec![1u8, 2, 3, 4];
-    /// let (rest, v) = Option::<u32>::read(input.bits(), Endian::Little).unwrap();
+    /// let (rest, v) = Option::<u32>::read(input.view_bits(), Endian::Little).unwrap();
     /// assert!(rest.is_empty());
     /// assert_eq!(v, Some(0x04030201))
     /// ```
@@ -699,7 +705,7 @@ mod tests {
             #[test]
             fn $test_name() {
                 let input = $input;
-                let bit_slice = input.bits::<Msb0>();
+                let bit_slice = input.view_bits::<Msb0>();
                 let (_rest, res_read) = <$typ>::read(bit_slice, ENDIAN).unwrap();
                 assert_eq!($expected, res_read);
 
@@ -792,7 +798,7 @@ mod tests {
         expected: u32,
         expected_rest: &BitSlice<Msb0, u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = match bit_size {
             Some(bit_size) => u32::read(bit_slice, (endian, BitSize(bit_size))).unwrap(),
@@ -830,7 +836,7 @@ mod tests {
         expected_rest: &BitSlice<Msb0, u8>,
         expected_write: Vec<u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = match bit_size {
             Some(bit_size) => u32::read(bit_slice, (endian, BitSize(bit_size))).unwrap(),
@@ -872,7 +878,7 @@ mod tests {
         expected: Vec<u8>,
         expected_rest: &BitSlice<Msb0, u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = match bit_size {
             Some(bit_size) => {
@@ -906,7 +912,7 @@ mod tests {
         expected_rest: &BitSlice<Msb0, u8>,
         expected_write: Vec<u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         // Unwrap here because all test cases are `Some`.
         let bit_size = bit_size.unwrap();
@@ -935,7 +941,7 @@ mod tests {
         expected: Ipv4Addr,
         expected_rest: &BitSlice<Msb0, u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = Ipv4Addr::read(bit_slice, endian).unwrap();
         assert_eq!(expected, res_read);
@@ -955,7 +961,7 @@ mod tests {
         expected: Ipv6Addr,
         expected_rest: &BitSlice<Msb0, u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = Ipv6Addr::read(bit_slice, endian).unwrap();
         assert_eq!(expected, res_read);
diff --git a/src/prelude.rs b/src/prelude.rs
index 83fe70e..46a3033 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -2,5 +2,5 @@ pub use crate::{
     error::DekuError, DekuContainerRead, DekuContainerWrite, DekuRead, DekuUpdate, DekuWrite,
 };
 pub use bitvec::{
-    order::BitOrder, order::Lsb0, order::Msb0, slice::AsBits, slice::BitSlice, vec::BitVec,
+    order::BitOrder, order::Lsb0, order::Msb0, slice::BitSlice, vec::BitVec, view::BitView,
 };
diff --git a/src/slice_impls.rs b/src/slice_impls.rs
index 2f43c26..b40a053 100644
--- a/src/slice_impls.rs
+++ b/src/slice_impls.rs
@@ -534,7 +534,7 @@ mod tests {
         expected: [u16; 2],
         expected_rest: &BitSlice<Msb0, u8>,
     ) {
-        let bit_slice = input.bits::<Msb0>();
+        let bit_slice = input.view_bits::<Msb0>();
 
         let (rest, res_read) = <[u16; 2]>::read(bit_slice, endian).unwrap();
         assert_eq!(expected, res_read);


Test patch:
diff --git a/tests/test_macro.rs b/tests/test_macro.rs
index 5bba1ad..9b25504 100644
--- a/tests/test_macro.rs
+++ b/tests/test_macro.rs
@@ -509,7 +509,7 @@ fn test_ctx_struct() {
 #[test]
 fn test_top_level_ctx_enum() {
     let test_data = [0x01_u8, 0x03];
-    let (rest, ret_read) = samples::TopLevelCtxEnum::read(test_data.bits(), (1, 2)).unwrap();
+    let (rest, ret_read) = samples::TopLevelCtxEnum::read(test_data.view_bits(), (1, 2)).unwrap();
     assert!(rest.is_empty());
     assert_eq!(ret_read, samples::TopLevelCtxEnum::VariantA(0x06));